Dizionari

I dizionari sono vettori associativi, quello che in altri linguaggi di programmazione viene anche indicato con "hash" o "mappings". Somigliano a liste, ma gli indici (keys o chiavi) sono stringhe, od altri oggetti Python immutabili, ad esempio tuple.

Internamente sono implementati con l'uso di 'hash tables', per cui le chiavi devono essere oggetti "hashables", cioe' Python deve poterli trasformare internamente in indirizzi; tutti gli oggetti immutabili hanno queste caratteristiche, ed anche oggetti istanze di classi create dall'utente soddisfano questo criterio.

Si chiamano dizionari perche' l'uso di stringhe per ritrovare elementi di un insieme e' analogo a quello che si fa quando si cerca una parola in un dizionario. Si usano per trattare insiemi di elementi contraddistinti da un nome, piuttosto che da un indice numerico, come per le liste.

I dizionari sono oggetti mutabili ed un dizionario puo' contenere oggetti eterogenei: numeri, stringhe, liste, dizionari. Si possono costruire strutture complesse con dizionari e liste annidate.

Gli elementi di un dizionario non hanno un ordine definito, e per individuare gli elementi si utilizza, al solito, una coppia di parentesi quadre, che contengono la chiave dell'elemento.

I dizionari non implementano gli operatori "=" e "*" come le liste. Per aggiungere un elemento basta definirne la chiave ed il valore.

Un dizionario e' rappresentato da coppie di chiavi e valori, separati da virgole, e racchiusi fra parentesi graffe.

Esempio:

D={'chiave':3,'altrachiave':6,1:'abcd'}

D['chiave']       : vale 3
D['altrachiave']  : vale 6
D[1]              : vale 'abcd'

D.get('chiave')   vale 3, ma se la chiave 3 non si trova da il valore None
                  invece di dare errore, come: D['chiave']

Come per le liste abbiamo che:

    D={}             : crea un dizionario vuoto
    D['a']=799.0     : aggiunge elemento, se la chiave esiste gia' lo modifica
    D[232]='s'

    D['b']=996       : crea elemento o lo modifica se c'e'
    D['b']=99        : cambia il valore dell'elemento con chiave 'b'

    del D['b']       : elimina l'elemento con chiave 'b'

    len(D)           : dimensione del dizionario: vale 3 se D ha 3 elementi

    D.pop('c')       : estrae dal dizionario il valore con chiave 'c' e lo elimina.

    D.update ( { 1: 10, 2: 20, 3:30 } ) :  unisce dizionari

D.clear()         : svuota il dizionario

D.pop(key)        : data la chiave, estrae l'elemento e lo elimina dal dizionario

Se abbiamo dizionari di dizionari possiamo reperire gli elementi del dizionario interno con la sintassi seguente:

D3={'cibo':{'carne':1,'frutta':2}} : dizionario che contiene un dizionario

D3['cibo']['frutta']               : e' l'elemento di valore 2

La funzione "in" e' riferita alle chiavi, ad esempio

D4={'a':0,'b':1,'c':3}

'a' in D4      :  e' True
0 in D4        :  e' False, 0 non e' una chiave di ricerca.

Un ciclo for sul dizionario restituisce le chiavi, ma si possono estrarre anche i valori o le coppie (chiave,valore) in una tupla:

    for i in D4:
       i

      restituisce 'a', al secondo ciclo 'b', poi 'c'

    D4.keys()   : restituisce un oggetto, che contiene le chiavi: ['a', 'c', 'b']
    D4.values() : restituisce un oggetto, che contiene  i valori: [0, 3, 1]
    D4.items()  : restituisce un oggetto, che contiene le tuple: chiave, valore:
                                         [('a', 0), ('c', 3), ('b', 1)]

sorted(D4) : solo in python 3, produce una lista ordinata di chiavi

La funzione items() permette di iterare sul dizionario estraendo una coppia: chiave, valore (una tupla)

for key,value in D4.items():
  ...

Le funzioni keys() e values() iterano risperrivamente su chiavi e valori. In Python 2 avevamo le funzioni "iteritems()" iterkeys() ed itervalues(), con significato analogo, ma sono state eliminate in Python 3.

In python 2 keys(), values() ed items() producevano liste, in Python3 oggetti su cui iterare e se se ne vuole fare una lista occorre convertirli con la funzione list: L=list(D4.keys())

La sintassi delle liste permette di implementare in modo compatto l'analogo dell'istruzione switch (o case) che hanno certi linguaggi di programmazione:

{'a':0,'b':1,'c':3}['b']   Questo vale 1

f={1:f1,2:f2,3:f3}[s]  questo vale f1 se s==0, f2 se s==1, f3 se s==2.
f()                    se f1,f2,f3 sono funzioni, posso eseguire cose
                       diverse a seconda del valore di s.

La funzione "dict" crea un dizionario a partire da liste di tuple, le chiavi si possono specificare in argomento o fornire in argomento una sequenza di tuple di 2 elementi: (chiave,valore):

D=dict(a:10,b='abc') : crea {'a':10,'b':'abc'}

D=dict( [('a',10),('b','abc')] )

D=dict( (('a',10),('b','abc'))

D=dict(  {'a': 10, 'b': 'abc'} )

La funzione "zip" permette di creare un dizionario a partire da 2 sequenze:

L1=['a','b','c'] ; L2=[0,1,2]
LX=zip(L1,L2)
LY=dict(zip(L1,L2))

In Python3 "zip" produce, a partire da due sequenze, un iterabile (in Python 2 una lista), con tuple di 2 elementi: ('a', 0), ('b', 1), ('c', 2)

La funzione "dict" trasforma l'iterabile in un dizionario:

{'a': 0, 'c': 2, 'b': 1}

In Python 3 (e Python 2.7) esiste una "dictionary comprehensions" ,analoga alla "list comprehension", che si puo' usare per definire gli elementi di un dizionario, si possono anche inserire operazioni e funzioni in una comprehension:

D={ x :x*x for x in [1,2,3] }   : genera: {1: 1, 2: 4, 3: 9}

D = {c: c * 4 for c in 'SPAM'}

produce: {'S': 'SSSS', 'P': 'PPPP', 'A': 'AAAA', 'M': 'MMMM'}

D = {c.lower(): c + '!' for c in ['SPAM', 'EGGS', 'HAM']}

produce: {'eggs': 'EGGS!', 'spam': 'SPAM!', 'ham': 'HAM!'}

Si puo anche usare la funzione zip, che unisce a 2 a 2, in tuple, gli elementi di due sequenze:

D = {k: v for (k, v) in zip(['a', 'b', 'c'], [1, 2, 3])}

               genera: {'b': 2, 'c': 3, 'a': 1}


D = {k: v for (k, v) in zip(['a', 'b', 'c'], [1, 2, 3]) if v%2 == 0 }

               genera: {'b': 2}  : ho tenuto solo numeri pari