16. I Dizionari
In questa lezione parleremo di un nuovo tipo di dato di Python: dict, che significa dictionary (in italiano dizionario).
I dizionari di Python
I dizionari sono simili al tipo di dato lista di cui abbiamo già parlato nelle lezioni precedenti, ma a differenza di queste, in cui ad ogni elemento corrisponde un indice progressivo quindi da 0 in su, nei dizionari ad ogni elemento è associata una chiave chiave, che potrà essere usata per accedere al valore dell'elemento.
Siamo noi a scegliere che chiave usare, e possiamo usare qualsiasi tipo di dato eccetto liste e altri dizionari. Per ogni elemento all'interno del dizionario avremo quindi una coppia chiave / valore.
I dizionari di Python vengono definiti utilizzando una coppia di parentesi graffe che contenga al suo interno delle coppie chiave / valore separate da due punti:
>>> mio_dict = {"mia_chiave": "mio_valore", "age": 29, 3.14: "pi greco", "primi": [2, 3, 5, 7]}
>>> type(mio_dict)
# output
<class 'dict'>
Quindi con questa azione abbiamo definito una struttura di dati contenente quattro coppie chiave : valore, associate al nome mio_dizionario. Come per tutte le variabili, possiamo accedere al valore in esse contenuto (nel nostro caso la struttura dati) tramite il nome stesso della variabile.
>>> mio_dict
# output
{"mia_chiave": "mio_valore", "age": 29, 3.14: "pi greco", "primi": [2, 3, 5, 7]}
Dizionari e coppie chiave valore
Come vedete abbiamo utilizzato diversi tipi di valori, stringhe, interi e liste, associati ciascuno ad una chiave univoca. Le chiavi nei dizionari sono proprio il corrispettivo degli indici nelle Liste: usiamo le chiavi per richiamare i valori ad esse associati.
Per ottenere il valore associato alla chiave mia_chiave_uno facciamo in questo modo:
>>> mio_dict["mia_chiave"]
'mio_valore'
Stesso discorso vale per tutti gli altri valori presenti, richiamabili tramite le loro chiavi. Proviamo a richiamare il valore associato alla chiave 3.14:
>>> mio_dict[3.14]
'pi greco'
Per aggiungere un nuovo elemento al nostro dizionario facciamo in questa maniera:
>>> mio_dict["nuova_chiave"] = "nuovo_valore"
>>> mio_dict
{'mia_chiave': 'mio_valore', 'age': 24, 3.14: 'pi greco', 'primi': [2, 3, 5, 7], 'nuova_chiave': 'nuovo_valore'}
Allo stesso modo possiamo sostituire il valore associato ad una chiave già presente nel dizionario:
>>> mio_dict["age"] = 99
>>> mio_dict
{'mia_chiave': 'mio_valore', 'age': 99, 3.14: 'pi greco', 'primi': [2, 3, 5, 7], 'nuova_chiave': 'nuovo_valore'}
Come verificare la presenza di elementi nei dizionari
Per verificare se una chiave è presente o meno all'interno di un dizionario possiamo utilizzare gli operatori in e not in:
>>> "age" in mio_dict
True
>>> "zen" in mio_dict
False
Come rimuovere elementi da un dizionario
Per rimuovere una coppia chiave-valore possiamo utilizzare l'istruzione del:
>>> del mio_dict["mia_chiave"]
>>> mio_dict
{'age': 99, 3.14: 'pi greco', 'primi': [2, 3, 5, 7], 'nuova_chiave': 'nuovo_valore'}
I metodi dei Dizionari di Python
Come per altri tipi di dato, anche il tipo dict dispone di alcuni metodi propri: analizziamo i principali con un nuovo esempio.
Definiamo un nuovo dizionario associato a una variabile ita_eng e inseriamoci i valori tipici di un dizionario Italiano - Inglese
ita_eng = {"ciao": "hello", "arrivederci": "goodbye", "uova": "eggs", "gatto": "cat", "arancia": "orange"}
Esistono tre metodi associati ai dizionari che ci consentono di ottenere in output una lista di tutte le chiavi presenti, o di tutti i valori presenti, o di entrambi allo stesso tempo: keys(), values() ed items().
Il metodo keys()
Keys è traducibile come "chiavi", ed è proprio il metodo che ci consente di ottenere una lista di tutte le chiavi presenti.
Quindi per ottenere una lista di tutte le chiavi presenti nel nostro dizionario ita_eng facciamo:
>>> ita_eng.keys()
# output
dict_keys(['ciao', 'arrivederci', 'uova', 'gatto', 'arancia'])
Metodo values()
Values significa valori, utilizziamo questo metodo per ottenere una lista di tutti i valori presenti:
>>> ita_eng.values()
# output
dict_values(['hello', 'goodbye', 'eggs', 'cat', 'orange'])
Il metodo items()
Infine utilizziamo il metodo items() per ottenere una lista di tutte le coppie chiavi-valore presenti.
>>> ita_eng.items()
# output
dict_items([('ciao', 'hello'), ('arrivederci', 'goodbye'), ('uova', 'eggs'), ('gatto', 'cat'), ('arancia', 'orange')])
Cosa restituiscono questi metodi?
Come possiamo interpretare dall'output, utilizzando questi metodi non ci vengono restituiti dei valori di tipi lista ma bensì, oggetti di tipo dict_keys, dict_values e dict_items.
Se abbiamo bisogno di una lista vera e propria possiamo utilizzare anche qui la nostra cara funzione list():
>>> parole_eng = list(ita_eng.keys())
>>> parole_eng
['ciao', 'arrivederci', 'uova', 'gatto', 'arancia']
Dizionari e cicli for
Possiamo inoltre utilizzare questi metodi in combinazione con un ciclo for.
Ad esempio, per mandare in print tutte le chiavi del dizionario possiamo fare:
for chiave in ita_eng.keys():
print(chiave)
# output
ciao
arrivederci
uova
gatto
arancia
Il metodo get()
Ma cosa succederebbe qualora provassimo a richiamare un valore associato a una chiave che non esiste nel nostro dizionario? Come è facile ipotizzare otterremmo un errore, e nello specifico un'eccezione del tipo KeyError, che se non gestita causerà il crash del programma.
>>> ita_eng["birra"]
# output
Traceback (most recent call last):
File "stdin", line 1, in module
KeyError: 'birra'
Parleremo di gestione degli errori più avanti nel corso introducendo delle istruzioni dedicate.
Alcuni/e tra voi a questo punto staranno però pensando: be, abbiamo visto come usare le istruzioni if ed else, perché non usare queste due per evitare il crash del programma? Potremmo in effetti fare qualcosa di questo tipo:
if "birra" in ita_eng.keys():
print(ita_eng["birra"])
else:
print("Chiave non trovata!")
# output
Chiave non trovata!
Il metodo funziona ma richiede parecchie righe di codice che dobbiamo scrivere da noi! E ricordate come uno dei concetti più importanti di cui abbiamo discusso sia il riutilizzo del codice?
Fortunatamente, i dizionari di Python dispongono di un metodo specifico ideato proprio per situazioni come queste: il metodo get(). A questo passiamo due parametri: la chiave per il valore che stiamo cercando, e un valore di default come una sorta di "paracadute d'emergenza", qualora la chiave richiesta non esista.
Richiamiamo il metodo get() sul nostro dizionario ita_eng e passiamogli la chiave birra, e come valore di default la stringa "Chiave non trovata, mi spiace!"
>>> ita_eng.get("birra", "Chiave non trovata, mi spiace!")
# output
'Chiave non trovata, mi spiace!'
Proviamo anche a chiamare il metodo passandoli una chiave stavolta esistente:
>>> ita_eng.get("ciao", "Chiave non trovata!!!")
# output
'hello'
Il Metodo setdefault()
Parallelamente a quanto fatto col metodo get(), ci saranno dei momenti in cui a seconda della complessità di ciò che stiamo facendo, potremmo avere la necessità di creare una coppia chiave valore qualora una chiave non sia già presente e associata a un valore nel dizionario.
Restando sull'esempio precedente, supponiamo di voler verificare se sia presente la chiave birra nel nostro dizionario e di volerla aggiungere assieme ad un valore di default qualora non sia già presente
>>> ita_eng
{'ciao': 'hello', 'arrivederci': 'goodbye', 'uova': 'eggs', 'gatto': 'cat', 'arancia': 'orange'}
>>> ita_eng.setdefault("birra", "beer")
"beer"
>>> ita_eng
{'ciao': 'hello', 'arrivederci': 'goodbye', 'uova': 'eggs', 'gatto': 'cat', 'arancia': 'orange', 'birra': 'beer'}
Il metodo setdefault() ha anzitutto cercato la chiave birra all'interno del dizionario ita_eng, e visto che la chiave non esisteva ha creato una coppia chiave-valore col valore beer da noi passato!