Senza categoria

Come e quando dovresti usare Defaultdict in Python?

In questo tutorial imparerai come usare defaultdict dal modulo delle raccolte di Python, per gestire meglio i KeyError, quando lavori con i dizionari Python.

In Python, un dizionario è una potente struttura dati incorporata che memorizza i dati in coppie chiave-valore. Utilizzerai i tasti per accedere al dizionario e accedere ai valori.

Tuttavia, quando nel tuo script Python sono presenti più dizionari che vengono modificati durante l’esecuzione del codice, ti imbatterai spesso in KeyErrors. E ci sono diversi modi in cui puoi gestirli.

In questo tutorial imparerai:

  • Cosa sono i KeyError e perché si verificano
  • Come gestire KeyError
  • Come usare defaultdict di Python, una sottoclasse che eredita dalla classe dict incorporata, per gestire meglio le chiavi mancanti

Cominciamo!

Cosa sono i KeyError in Python?

Quando si definisce un dizionario Python, è necessario prestare attenzione a garantire quanto segue:

  • Le chiavi dovrebbero essere uniche, senza alcuna ripetizione.
  • Quando si utilizza un iterabile esistente come chiavi di un dizionario, è preferibile utilizzare una raccolta immutabile come una tupla.

Quindi una chiave è valida solo se è presente nel dizionario; altrimenti porta a KeyErrors.

Si consideri il seguente dizionario, libri_autori, in cui le chiavi sono i nomi dei libri ei valori sono i nomi degli autori.

Puoi programmare insieme a questo tutorial in Python REPL.

books_authors = {
    'Deep Work':'Cal Newport',
    'Hyperfocus':'Chris Bailey',
    'Pivot':'Jenny Blake',
    'The Happiness Equation':'Neil Pasricha'
}

Puoi usare la chiave (nome del libro) per accedere al nome dell’autore.

books_authors['Hyperfocus']
'Chris Bailey'

Per accedere a tutte le coppie chiave-valore nel dizionario, puoi chiamare il metodo items() sull’oggetto dizionario, come mostrato di seguito:

for book,author in books_authors.items():
  print(f"'{book}' by {author}")
'Deep Work' by Cal Newport
'Hyperfocus' by Chris Bailey
'Pivot' by Jenny Blake
'The Happiness Equation' by Neil Pasricha

Se si tenta di accedere al valore di una chiave che non è presente nel dizionario, l’interprete Python genera un KeyError. Ci imbattiamo in KeyError quando proviamo ad accedere al valore di chiavi che non esistono, ovvero “Grit” e “Chiave inesistente”.

books_authors['Grit']
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
<ipython-input-6-e1a4486f5ced> in <module>
----> 1 books_authors['Grit']

KeyError: 'Grit'
books_authors['non-existent-key']
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
<ipython-input-7-a3efd56f69e5> in <module>
----> 1 books_authors['non-existent-key']

KeyError: 'non-existent-key'

Quindi, come gestisci KeyError in Python?

Ci sono alcuni modi per farlo e li impareremo nella prossima sezione.

Come gestire gli errori di chiave in Python

Impariamo come gestire KeyError usando:

  • Dichiarazioni condizionali if-else
  • Blocchi try-eccetto
  • Il metodo del dizionario .get()

# 1. Utilizzo di istruzioni condizionali If-Else

Uno dei modi più semplici per gestire KeyError in Python è usare le istruzioni condizionali if-else.

In Python, le istruzioni if-else hanno la seguente sintassi generale:

 if condition:
 	# do this 
 else:
    # do something else 
  • Se la condizione è True, le istruzioni nel corpo if vengono eseguite e
  • Se la condizione è False, le istruzioni nel corpo else vengono eseguite.

In questo esempio, la condizione è verificare se la chiave è presente nel dizionario.

Se la chiave è presente nel dizionario, l’operatore in restituirà True e se body verrà eseguito stampando il valore corrispondente.

key = 'The Happiness Equation'
if key in books_authors:
  print(books_authors[key])
else:
  print('Sorry, this key does not exist!')

# Output
# Neil Pasricha

Se la chiave non è presente nel dizionario, l’operatore in restituisce False e verrà eseguito il corpo else. Stampa un messaggio che la chiave non è presente.

key = 'non-existent-key'
if key in books_authors:
  print(books_authors[key])
else:
  print('Sorry, this key does not exist!')

# Output
# Sorry, this key does not exist!

#2. Utilizzo di dichiarazioni Try-Except

Un altro metodo comune per gestire KeyError è usare le istruzioni try-except in Python.

Leggi il seguente blocco di codice:

key = 'non-existent-key'
try:
  print(books_authors[key])
except KeyError:
  print('Sorry, this key does not exist!')
  • Il blocco try tenta di recuperare il valore corrispondente alla chiave fornita.
  • Se la chiave non è presente, l’interprete solleva un KeyError che viene gestito come un’eccezione all’interno del blocco di eccezione.

#3. Utilizzando il metodo .get()

In Python, puoi usare il metodo del dizionario integrato .get() per gestire le chiavi mancanti.

La sintassi generale per utilizzare il metodo get() è dict.get(key,default_value) dove dict è un oggetto dizionario valido in Python.

– Se la chiave è presente nel dizionario, il metodo get() restituisce il valore.
– Altrimenti, restituisce il valore predefinito.

In questo esempio, keys è un elenco di chiavi a cui vorremmo accedere ai valori. Scorriamo l’elenco delle chiavi per recuperare i valori corrispondenti dal dizionario books_authors.

Qui, abbiamo utilizzato il metodo .get() con ‘Non esiste’ come valore predefinito.

keys = ['Grit','Hyperfocus','Make Time','Deep Work']
for key in keys:
  print(books_authors.get(key,'Does not exist'))

Nel codice sopra:

  • Per le chiavi presenti nel dizionario books_authors, il metodo .get() restituisce i valori corrispondenti.
  • Quando le chiavi non esistono, in questo caso, ‘Grit’ e ‘Make Time’, il metodo .get() restituisce il valore predefinito ‘Non esiste’.
# Output

Does not exist
Chris Bailey
Does not exist
Cal Newport

Tutti i metodi di cui sopra ci aiutano a gestire gli errori chiave. Tuttavia, sono dettagliati e ci richiedono di gestire esplicitamente le chiavi mancanti. Puoi semplificare questo processo usando un defaultdict invece di un dizionario normale.

Predefinito in Python

Il defaultdict è una sottoclasse della classe del dizionario (dict). Quindi eredita il comportamento di un dizionario Python. Inoltre, gestisce anche le chiavi mancanti in modo nativo.

Il defaultdict è un tipo di dati contenitore integrato nella libreria standard di Python, all’interno del modulo delle raccolte.

Quindi devi importarlo nel tuo ambiente di lavoro:

from collections import defaultdict

Ecco la sintassi generale per utilizzare defaultdict:

defaultdict(default_factory)

È possibile specificare un callable come int, float o list come attributo default_factory. Se non fornisci un valore per default_factory, il valore predefinito è Nessuno.

Quando la chiave che stai cercando non è presente, viene attivato il metodo __missing__() e deduce il valore predefinito da default_factory. Quindi restituisce questo valore predefinito.

In sintesi:

  • In Python, un defaultdict restituisce il valore predefinito quando la chiave non è presente.
  • Aggiunge anche questa coppia chiave-valore predefinito al dizionario, che puoi quindi modificare.

Esempi di Python Defaultdict

Successivamente, codificheremo alcuni esempi per capire come funziona Python defaultdict.

Defaultdict in Python con valore intero predefinito

Innanzitutto, importa defaultdict dal modulo delle raccolte.

from collections import defaultdict
import random

Creiamo un defaultdict prezzi.

prices = defaultdict(int)

Popoliamo ora il dizionario dei prezzi utilizzando gli elementi della lista dei frutti come chiavi. E campioniamo casualmente i valori dal listino prezzi per ottenere i valori.

price_list = [10,23,12,19,5]
fruits = ['apple','strawberry','pomegranate','blueberry']

for fruit in fruits:
  prices[fruit] = random.choice(price_list)

Diamo un’occhiata alle coppie chiave-valore nel defaultdict dei prezzi.

print(prices.items())
dict_items([('apple', 12), ('blueberry', 19), ('pomegranate', 5), ('strawberry', 10)])

Come un normale dizionario Python, puoi accedere ai valori di defaultdict dei prezzi usando le chiavi:

prices['apple']
# 23

Ora, proviamo ad accedere al prezzo di un frutto che non è presente, diciamo, ‘arancia’. Vediamo che restituisce il valore predefinito di zero.

prices['orange']
# 0

Se stampiamo il dizionario, vediamo che è stata aggiunta una nuova chiave “arancione” con il valore intero predefinito pari a zero.

print(prices.items())
dict_items([('apple', 12), ('blueberry', 19), ('pomegranate', 5), ('strawberry', 10), ('orange', 0)])

Defaultdict in Python con List come valore predefinito

Definiamo student_majors come un defaultdict di liste. I nomi delle major sono le chiavi. E i valori sono gli elenchi di studenti che perseguono ciascuna delle major, come matematica, economia, informatica e altro ancora.

from collections import defaultdict
students_majors = defaultdict(list)

Se proviamo ad accedere all’elenco studenti corrispondente a ‘Economia’, defaultdict restituisce un elenco vuoto; nessun errore chiave!

students_majors['Economics']
# []

Ora abbiamo una lista vuota mappata alla specializzazione in “Economia”. Quindi ora possiamo aggiungere elementi a questa lista usando il metodo list .append().

students_majors['Economics'].append('Alex')

È stata creata una voce per ‘Economia’ nel dizionario predefinito Students_Majors.

print(students_majors)
defaultdict(<class 'list'>, {'Economics': ['Alex']})

Puoi aggiungere più studenti alla mappatura dell’elenco alla specializzazione in Economia, aggiungere una nuova specializzazione e molto altro!

students_majors['Economics'].append('Bob')
students_majors['Math'].append('Laura')
print(students_majors)
defaultdict(<class 'list'>, {'Economics': ['Alex', 'Bob'], 'Math': ['Laura']})

Conclusione

Spero che questo tutorial ti abbia aiutato a capire come e quando dovresti usare defaultdict in Python. Dopo aver eseguito gli esempi di codice in questo tutorial, puoi provare a usare defaultdict come struttura dati preferita nei tuoi progetti quando necessario.

Ecco un riassunto di ciò che hai imparato in questo tutorial.

  • Quando lavori con un dizionario Python, ti imbatterai spesso in KeyErrors.
  • Per gestire tali KeyError puoi usare alcuni metodi dettagliati. È possibile utilizzare istruzioni condizionali, blocchi try-except o il metodo .get(). Ma il tipo di dati defaultdict nel modulo delle raccolte può semplificare questa gestione di KeyError.
  • È possibile utilizzare defaultdict(default_factory) dove default_factory è un callable valido.
  • Quando la chiave non è presente nel defaultdict, il valore predefinito (dedotto da default_factory) e la chiave vengono aggiunti al defaultdict.

Quindi, dai un’occhiata al tutorial sulla funzione della mappa di Python.