Diccionaris

Què son?

Els diccionaris

Un tipus associatiu associa un valor a una clau

  • les claus són un conjunt finit i no es repeteixen

  • el mateix valor pot estar associat a dues claus diferents

  • correspon al concepte matemàtic d’aplicació o funció

Les claus d’un diccionari

  • han de ser de tipus immutables

  • i si són contenidors (tuples, per exemple), els seus elements també han de ser immutables

Com es construeixen?

  • Un valor literal de tipus dict és una llista de parelles clau-valor separades per comes (,) i escrites entre claus ({})

  • En una parella clau-valor, la clau es separa del valor per dos punts (:)

  • Exemples

    >>> eng2cat = {'two': 'dos', 'one': 'un', 'three' : 'tres'}
    >>> eng2cat
    {'two': 'dos', 'one': 'un', 'three': 'tres'}
    

Operacions de consulta

  • Longitud: quantes parells clau-valor té el diccionari?

    >>> len(eng2cat)
    3
    
  • Pertinença (in, not in): la clau pertany al diccionari?

    >>> 'two' in eng2cat
    True
    
  • Accés per clau, mètode get(): quin és el valor associat a una clau?

    >>> eng2cat['two']
    'dos'
    >>> eng2cat[2]
    Traceback (most recent call last):
      File "<python-input-1>", line 1, in <module>
        eng2cat[2]
        ~~~~~~~^^^
    KeyError: 2
    
    >>> eng2cat.get('two', '')
    'dos'
    >>> eng2cat.get(2, '')
    ''
    
    >>> valor_per_defecte = ''
    >>> clau = 2
    >>> if clau in eng2cat:
    ...     valor = eng2cat[clau]
    ... else:
    ...     valor = valor_per_defecte
    >>> valor
    ''
    
  • Igualtat (==, !=): tenen les mateixes parelles clau-valor?

    >>> d1 = {'un': 1, 'dos': 2}
    >>> d1 == {'dos': 2, 'un': 1}
    True
    >>> d1 == {'un': 'one', 'dos': 'two'}
    False
    >>> d1 == {'one': 1, 'two': 2}
    False
    
  • Funcions predefinides (max(), min()): quina és la clau més gran (més petita)?

    >>> max(eng2cat)
    'two'
    >>> min(eng2cat)
    'one'
    

Vistes

  • Claus, valors i parelles clau-valor

    >>> vk = eng2cat.keys()
    >>> vk
    dict_keys(['two', 'one', 'three'])
    
    >>> vv = eng2cat.values()
    >>> vv
    dict_values(['dos', 'un', 'tres'])
    
    >>> vi = eng2cat.items()
    >>> vi
    dict_items([('two', 'dos'), ('one', 'un'), ('three', 'tres')])
    

Conversió de tipus

  • Seqüència de les claus, els valors o les parelles clau-valor

    >>> d = {1: 'u', 'dos': 2}
    >>> d_k = d.keys()
    >>> d_v = d.values()
    >>> d_i = d.items()
    
    >>> list(d)
    [1, 'dos']
    >>> tuple(d_k)
    (1, 'dos')
    
    >>> list(d_v)
    ['u', 2]
    
    >>> list(d_i)
    [(1, 'u'), ('dos', 2)]
    
  • Diccionari a partir d’una seqüència de parelles clau-valor

    >>> l = [('a', 3), ('b', 9), ('c', 5)]
    >>> dict(l)
    {'a': 3, 'b': 9, 'c': 5}
    

Mutabilitat

  • Els diccionaris són objectes mutables

  • Tenen operacions per afegir, modificar i esborrar parelles clau-valor

Operacions modificadores

  • Afegir una parella clau-valor

    >>> 'four' in eng2cat
    False
    >>> eng2cat['four'] = 'quatre'
    >>> eng2cat
    {'two': 'dos', 'one': 'un', 'three': 'tres', 'four': 'quatre'}
    
    >>> vk
    dict_keys(['two', 'one', 'three', 'four'])
    >>> vv
    dict_values(['dos', 'un', 'tres', 'quatre'])
    >>> vi
    dict_items([('two', 'dos'), ('one', 'un'), ('three', 'tres'), ('four', 'quatre')])
    
  • Modificar el valor associat a una clau

    >>> 'two' in eng2cat
    True
    >>> eng2cat['two'] = 2
    >>> eng2cat
    {'two': 2, 'one': 'un', 'three': 'tres', 'four': 'quatre'}
    
  • Esborrar una parella clau-valor

    >>> del eng2cat['two']
    >>> eng2cat
    {'one': 'un', 'three': 'tres', 'four': 'quatre'}
    

Generació de diccionaris

  • A partir d’un diccionari buit

    >>> polinomi = {}                # p(x) = 0
    
  • Afegint parelles clau-valor

    >>> polinomi[5] = 3              # p(x) = 3x⁵
    >>> polinomi[0] = -1             # p(x) = 3x⁵ - 1
    >>> polinomi
    {5: 3, 0: -1}
    

Iteració de diccionaris

  • Els diccionaris són iterables (com les seqüències)

    >>> for clau in eng2cat:
    ...     print(clau)
    one
    three
    four
    
  • Les vistes d’un diccionari també són iterables

    >>> for clau in vk:
    ...     print(clau)
    one
    three
    four
    
    >>> for valor in vv:
    ...     print(valor)
    un
    tres
    quatre
    
    >>> for clau, valor in vi:
    ...     print(clau, valor)
    one un
    three tres
    four quatre
    

Algorismes sobre diccionaris

Diccionaris per comprensió

  • Un diccionari per comprensió és una sintaxi compacta per calcular un diccionari a partir dels elements d’un iterable o només d’una part.

  • Exemples

    • Diccionari dels nombres parells d’un iterable i dels seus quadrat

      >>> nombres = [5, 2, 7, 3, 8, 1, 6]
      >>> pq = {n: n**2 for n in nombres if n%2 == 0}
      >>> pq
      {2: 4, 8: 64, 6: 36}
      
    • Diccionari de vocals i valors associats iguals a zero

      >>> dv = {v: 0 for v in 'aeiou'}
      >>> dv
      {'a': 0, 'e': 0, 'i': 0, 'o': 0, 'u': 0}
      

Diccionaris imbricats

Qualsevol combinació de diccionaris i seqüències és vàlida

  • diccionaris de diccionaris

    >>> dd = {
    ...   'Joan': {'casa': '936 513 792', 'mòbil': '732 864 715'},
    ...   'Anna': {'feina': '934 902 865'}
    ... }
    
  • diccionaris de llistes

    >>> dl = {
    ...   'Maria': [8.4, 10, 7.3],
    ...   'Pere': [5.7, 4.2]
    ... }
    
  • llistes de diccionaris

    >>> ld = [
    ...   {'codi': 'XZ-3', 'preu': 35.7, 'iva': 21},
    ...   {'codi': 'TW-45', 'preu': 12.83, 'iva': 10, 'estoc': 51}
    ... ]
    

Còpies

  • Mètode copy(): com obtenir una còpia superficial d’un diccionari?

    >>> opposites = {'up': 'down', 'right': 'wrong', 'true': 'false'}
    
    >>> copia = opposites.copy()
    >>> copia is opposites
    False
    >>> copia == opposites
    True
    
    >>> mateix = opposites
    >>> mateix is opposites
    True
    

Exercicis