Comment et quand utiliser Defaultdict en Python ?

Dans ce didacticiel, vous apprendrez à utiliser defaultdict du module de collections de Python (pour mieux gérer les KeyErrors) lorsque vous travaillez avec des dictionnaires Python.

En Python, un dictionnaire est une puissante structure de données intégrée qui stocke les données dans des paires clé-valeur. Vous utiliserez les touches pour puiser dans le dictionnaire et accéder aux valeurs.

Cependant, lorsque vous avez plusieurs dictionnaires dans votre script Python qui sont modifiés lors de l’exécution du code, vous rencontrerez souvent des KeyErrors. Et il existe plusieurs façons de les gérer.

Dans ce tutoriel, vous apprendrez :

  • Que sont les KeyErrors et pourquoi surviennent-elles
  • Comment gérer les KeyErrors
  • Comment utiliser le defaultdict de Python, une sous-classe qui hérite de la classe dict intégrée, pour mieux gérer les clés manquantes

Commençons!

Que sont les KeyErrors en Python ?

Lors de la définition d’un dictionnaire Python, vous devez vous assurer que vous devez vous assurer que :

  • Les clés doivent être uniques – sans aucune répétition.
  • Lorsque vous utilisez un itérable existant comme clés d’un dictionnaire, vous devez préférer utiliser une collection immuable telle qu’un tuple.

Ainsi une clé n’est valide que si elle est présente dans le dictionnaire ; sinon, cela conduit à KeyErrors.

Considérez le dictionnaire suivant, books_authors, dans lequel les clés sont les noms des livres et les valeurs sont les noms des auteurs.

Vous pouvez coder avec ce tutoriel dans un REPL Python.

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

Vous pouvez utiliser la clé (nom du livre) pour accéder au nom de l’auteur.

books_authors['Hyperfocus']
'Chris Bailey'

Pour accéder à toutes les paires clé-valeur du dictionnaire, vous pouvez appeler la méthode items() sur l’objet dictionnaire, comme illustré ci-dessous :

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

Si vous essayez d’accéder à la valeur d’une clé qui n’est pas présente dans le dictionnaire, l’interpréteur Python lève une KeyError. Nous rencontrons KeyError lorsque nous essayons d’accéder à la valeur de clés qui n’existent pas, à savoir ‘Grit’ et ‘clé inexistante’.

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'

Alors, comment gérez-vous KeyErrors en Python ?

Il existe plusieurs façons de le faire, et nous les apprendrons dans la section suivante.

Comment gérer les erreurs de clé en Python

Apprenons à gérer les KeyErrors en utilisant :

  • Instructions conditionnelles if-else
  • Try-except blocs
  • La méthode du dictionnaire .get()

#1. Utilisation d’instructions conditionnelles If-Else

L’un des moyens les plus simples de gérer les KeyErrors en Python consiste à utiliser les instructions conditionnelles if-else.

En Python, les instructions if-else ont la syntaxe générale suivante :

 if condition:
 # do this 
 else:
    # do something else 
  • Si la condition est True, les instructions du corps if sont exécutées, et
  • Si la condition est False, les instructions du corps else sont exécutées.

Dans cet exemple, la condition est de vérifier si la clé est présente dans le dictionnaire.

Si la clé est présente dans le dictionnaire, l’opérateur in renverra True et if body sera exécuté en affichant la valeur correspondante.

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

# Output
# Neil Pasricha

Si la clé n’est pas présente dans le dictionnaire, l’opérateur in renvoie False et le corps else sera exécuté. Il imprime un message indiquant que la clé n’est pas présente.

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. Utilisation d’instructions Try-Except

Une autre méthode courante pour gérer KeyError consiste à utiliser les instructions try-except en Python.

Lisez le bloc de code suivant :

key = 'non-existent-key'
try:
  print(books_authors[key])
except KeyError:
  print('Sorry, this key does not exist!')
  • Le bloc try tente de récupérer la valeur correspondant à la clé fournie.
  • Si la clé n’est pas présente, l’interpréteur lève une KeyError qui est traitée comme une exception dans le bloc except.

#3. Utilisation de la méthode .get()

En Python, vous pouvez utiliser la méthode de dictionnaire intégrée .get() pour gérer les clés manquantes.

La syntaxe générale pour utiliser la méthode get() est dict.get(key,default_value) où dict est un objet dictionnaire valide en Python.

– Si la clé est présente dans le dictionnaire, alors la méthode get() renvoie la valeur.
– Sinon, il renvoie la valeur par défaut.

Dans cet exemple, keys est une liste de clés dont nous aimerions accéder aux valeurs. Nous parcourons la liste des clés pour récupérer les valeurs correspondantes du dictionnaire books_authors.

Ici, nous avons utilisé la méthode .get() avec ‘N’existe pas’ comme valeur par défaut.

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

Dans le code ci-dessus :

  • Pour les clés présentes dans le dictionnaire books_authors, la méthode .get() renvoie les valeurs correspondantes.
  • Lorsque les clés n’existent pas, dans ce cas, ‘Grit’ et ‘Make Time’, la méthode .get() renvoie la valeur par défaut ‘Does not exist’.
# Output

Does not exist
Chris Bailey
Does not exist
Cal Newport

Toutes les méthodes ci-dessus nous aident à gérer les erreurs clés. Cependant, ils sont verbeux et nous obligent à gérer explicitement les clés manquantes. Vous pouvez simplifier ce processus en utilisant un defaultdict au lieu d’un dictionnaire ordinaire.

Defaultdict en Python

defaultdict est une sous-classe de la classe du dictionnaire (dict). Il hérite donc du comportement d’un dictionnaire Python. De plus, il gère également les clés manquantes de manière native.

Le defaultdict est un type de données de conteneur intégré à la bibliothèque standard Python – à l’intérieur du module collections.

Vous devez donc l’importer dans votre environnement de travail :

from collections import defaultdict

Voici la syntaxe générale pour utiliser defaultdict :

defaultdict(default_factory)

Vous pouvez spécifier un callable tel que int, float ou list comme attribut default_factory. Si vous ne fournissez pas de valeur pour default_factory, la valeur par défaut est None.

Lorsque la clé que vous recherchez n’est pas présente, la méthode __missing__() est déclenchée et elle déduit la valeur par défaut de default_factory. Il renvoie ensuite cette valeur par défaut.

En résumé:

  • En Python, un defaultdict renvoie la valeur par défaut lorsque la clé n’est pas présente.
  • Il ajoute également cette paire clé-valeur par défaut au dictionnaire, que vous pouvez ensuite modifier.

Exemples Python Defaultdict

Ensuite, nous allons coder quelques exemples pour comprendre le fonctionnement de Python defaultdict.

Defaultdict en Python avec une valeur entière par défaut

Tout d’abord, importez defaultdict depuis le module collections.

from collections import defaultdict
import random

Créons un prix defaultdict.

prices = defaultdict(int)

Nous remplissons maintenant le dictionnaire des prix en utilisant les éléments de la liste des fruits comme clés. Et nous échantillonnons au hasard des valeurs de la liste de prix pour obtenir les valeurs.

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

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

Examinons les paires clé-valeur dans les prix defaultdict.

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

Comme un dictionnaire Python normal, vous pouvez accéder aux valeurs des prix defaultdict en utilisant les clés :

prices['apple']
# 23

Maintenant, essayons d’accéder au prix d’un fruit qui n’est pas présent, disons, ‘orange’. Nous voyons qu’il renvoie la valeur par défaut de zéro.

prices['orange']
# 0

Si nous imprimons le dictionnaire, nous voyons qu’une nouvelle clé ‘orange’ a été ajoutée avec la valeur entière par défaut de zéro.

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

Defaultdict en Python avec List comme valeur par défaut

Définissons les étudiants_majors comme un dict de listes par défaut. Les noms des majors sont les clés. Et les valeurs sont les listes d’étudiants poursuivant chacune des majeures, telles que les mathématiques, l’économie, l’informatique, etc.

from collections import defaultdict
students_majors = defaultdict(list)

Si nous essayons d’accéder à la liste des étudiants correspondant à ‘Economie’, defaultdict renvoie une liste vide ; aucune erreur de clé !

students_majors['Economics']
# []

Nous avons maintenant une liste vide mappée à la majeure « Économie ». Nous pouvons donc maintenant ajouter des éléments à cette liste en utilisant la méthode de liste .append().

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

Une entrée a été créée pour ‘Économie’ dans le dictionnaire par défaut des étudiants_majors.

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

Vous pouvez ajouter plus d’étudiants à la liste de correspondance avec la majeure en économie, ajouter une nouvelle majeure et bien plus encore !

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

Conclusion

J’espère que ce tutoriel vous a aidé à comprendre comment et quand utiliser defaultdict en Python. Après avoir exécuté les exemples de code de ce didacticiel, vous pouvez essayer d’utiliser defaultdict comme structure de données préférée dans vos projets si nécessaire.

Voici un résumé de ce que vous avez appris dans ce tutoriel.

  • Lorsque vous travaillez avec un dictionnaire Python, vous rencontrez souvent des KeyErrors.
  • Pour gérer ces KeyErrors, vous pouvez utiliser quelques méthodes détaillées. Vous pouvez utiliser des instructions conditionnelles, des blocs try-except ou la méthode .get(). Mais le type de données defaultdict dans le module collections peut simplifier cette gestion KeyError.
  • Vous pouvez utiliser defaultdict(default_factory) où default_factory est un callable valide.
  • Lorsque la clé n’est pas présente dans le defaultdict, la valeur par défaut (déduite de default_factory) et la clé sont ajoutées au defaultdict.

Ensuite, consultez le didacticiel sur la fonction de carte Python.