Dans ce tutoriel, nous allons explorer la structure de données defaultdict en Python, qui est une variante puissante du dictionnaire standard qui gère les clés manquantes de manière gracieuse. Plus précisément, nous allons apprendre à créer un defaultdict avec une valeur par défaut de 0, ce qui est particulièrement utile pour compter et accumuler des valeurs dans vos programmes Python.
À la fin de ce laboratoire, vous comprendrez ce qu'est un defaultdict, comment en créer un avec une valeur par défaut de 0, et comment l'appliquer dans des scénarios pratiques pour écrire un code plus élégant et résistant aux erreurs.
Comprendre le problème des dictionnaires classiques
Avant d'approfondir defaultdict, commençons par comprendre la limitation des dictionnaires classiques que defaultdict nous aide à résoudre.
Le problème de KeyError
En Python, le dictionnaire standard (dict) est utilisé pour stocker des paires clé-valeur. Cependant, lorsque vous essayez d'accéder à une clé qui n'existe pas dans un dictionnaire classique, Python lève une KeyError.
Créeons un exemple simple pour démontrer ce problème :
Créez un nouveau fichier appelé regular_dict_demo.py dans l'éditeur :
## Crée un dictionnaire classique pour compter les fruits
fruit_counts = {}
## Essayez d'incrémenter le compte pour 'apple'
try:
fruit_counts['apple'] += 1
except KeyError:
print("KeyError: la clé 'apple' n'existe pas dans le dictionnaire")
## La manière appropriée de faire cela avec les dictionnaires classiques
if 'banana' in fruit_counts:
fruit_counts['banana'] += 1
else:
fruit_counts['banana'] = 1
print(f"Compte des fruits : {fruit_counts}")
Exécutez le script à partir du terminal :
python3 regular_dict_demo.py
Vous devriez voir une sortie similaire à :
KeyError: la clé 'apple' n'existe pas dans le dictionnaire
Compte des fruits : {'banana': 1}
Comme vous pouvez le voir, essayer d'incrémenter le compte pour une clé qui n'existe pas provoque une erreur. La solution habituelle consiste à vérifier si la clé existe avant d'essayer de l'accéder, ce qui conduit à un code plus verbeux.
C'est là que defaultdict vient en aide - il gère automatiquement les clés manquantes en les créant avec une valeur par défaut lorsqu'elles sont accessibles.
Présentation de defaultdict avec une valeur par défaut de 0
Maintenant que nous comprenons le problème des dictionnaires classiques, apprenons à utiliser defaultdict pour le résoudre.
Qu'est-ce que defaultdict?
Le defaultdict est une sous-classe de la classe dict intégrée de Python qui accepte une fonction (appelée "usine par défaut") comme premier argument. Lorsqu'une clé est accédée et qu'elle n'existe pas, defaultdict crée automatiquement cette clé avec une valeur renvoyée par la fonction d'usine par défaut.
Création d'un defaultdict avec une valeur par défaut de 0
Créons un defaultdict qui fournit une valeur par défaut de 0 pour toute clé manquante :
Créez un nouveau fichier appelé default_dict_zero.py dans l'éditeur :
## Tout d'abord, importez la classe defaultdict du module collections
from collections import defaultdict
## Méthode 1 : Utilisation de int comme usine par défaut
## La fonction int() appelée sans arguments renvoie 0
compteur = defaultdict(int)
print("État initial du compteur :", dict(compteur))
## Accédez à une clé qui n'existe pas encore
print("Valeur pour 'apple' (avant) :", compteur['apple'])
## Incrémentez le compte
compteur['apple'] += 1
compteur['apple'] += 1
compteur['banana'] += 1
print("Valeur pour 'apple' (après) :", compteur['apple'])
print("Dictionnaire après les opérations :", dict(compteur))
## Méthode 2 : Utilisation d'une fonction lambda (approche alternative)
compteur2 = defaultdict(lambda: 0)
print("\nUtilisation d'une fonction lambda :")
print("Valeur pour 'cerise' (avant) :", compteur2['cerise'])
compteur2['cerise'] += 5
print("Valeur pour 'cerise' (après) :", compteur2['cerise'])
print("Dictionnaire après les opérations :", dict(compteur2))
Exécutez le script à partir du terminal :
python3 default_dict_zero.py
Vous devriez voir une sortie similaire à :
État initial du compteur : {}
Valeur pour 'apple' (avant) : 0
Valeur pour 'apple' (après) : 2
Dictionnaire après les opérations : {'apple': 2, 'banana': 1}
Utilisation d'une fonction lambda :
Valeur pour 'cerise' (avant) : 0
Valeur pour 'cerise' (après) : 5
Dictionnaire après les opérations : {'cerise': 5}
Comment ça fonctionne
Lorsque nous créons defaultdict(int), nous disons à Python d'utiliser la fonction int() comme usine par défaut. Lorsqu'elle est appelée sans arguments, int() renvoie 0, qui devient la valeur par défaut pour toute clé manquante.
De manière similaire, nous pouvons utiliser une fonction lambda lambda: 0 qui renvoie simplement 0 lorsqu'elle est appelée.
Remarquez comment nous pouvons accéder directement et incrémenter les valeurs pour des clés qui n'existaient pas auparavant, sans rencontrer d'erreurs.
Cas d'utilisation pratique : Compter les fréquences des mots
L'une des applications les plus courantes de defaultdict avec une valeur par défaut de 0 est le comptage des fréquences. Implémentons un compteur de fréquences de mots pour démontrer ce cas d'utilisation pratique.
Créez un nouveau fichier appelé word_counter.py dans l'éditeur :
from collections import defaultdict
def count_word_frequencies(text):
## Crée un defaultdict avec une valeur par défaut de 0
word_counts = defaultdict(int)
## Divise le texte en mots et les convertit en minuscules
words = text.lower().split()
## Nettoie chaque mot (enlève la ponctuation) et compte les occurrences
for word in words:
## Enlève la ponctuation commune
clean_word = word.strip('.,!?:;()"\'')
if clean_word: ## Ignore les chaînes vides
word_counts[clean_word] += 1
return word_counts
## Teste la fonction avec un texte d'échantillonnage
sample_text = """
Python est incroyable! Python est facile à apprendre, et Python est très puissant.
Avec Python, vous pouvez créer des applications web, analyser des données, construire des jeux,
et automatiser des tâches. La syntaxe de Python est claire et lisible.
"""
word_frequencies = count_word_frequencies(sample_text)
## Affiche les résultats
print("Fréquences des mots :")
for word, count in sorted(word_frequencies.items()):
print(f" {word}: {count}")
## Trouve les mots les plus courants
print("\nMots les plus courants :")
sorted_words = sorted(word_frequencies.items(), key=lambda x: x[1], reverse=True)
for word, count in sorted_words[:5]: ## Les 5 premiers mots
print(f" {word}: {count}")
Exécutez le script à partir du terminal :
python3 word_counter.py
Vous devriez voir une sortie similaire à :
Fréquences des mots :
incroyable: 1
analyser: 1
et: 3
applications: 1
automatiser: 1
construire: 1
pouvez: 1
claire: 1
créer: 1
données: 1
facile: 1
jeux: 1
est: 4
apprendre: 1
puissant: 1
python: 4
python's: 1
lisible: 1
syntaxe: 1
tâches: 1
à: 1
très: 1
web: 1
avec: 1
vous: 1
Mots les plus courants :
python: 4
est: 4
et: 3
incroyable: 1
facile: 1
Comment ça fonctionne
Nous créons un defaultdict(int) pour stocker les comptes de mots avec une valeur par défaut de 0
Nous traitons chaque mot dans le texte, en nettoyant la ponctuation
Nous incrémentons simplement le compte pour chaque mot en utilisant word_counts[word] += 1
Pour les mots apparaissant pour la première fois, la valeur par défaut de 0 est automatiquement assignée
Cette approche est considérablement plus propre et plus efficace que d'utiliser un dictionnaire classique avec des vérifications d'existence.
Avantages d'utiliser defaultdict avec une valeur par défaut de 0
Code simplifié : Pas besoin de vérifier si les clés existent avant d'incrémenter
Moins de lignes de code : Supprime les vérifications d'existence de clés de base
Erreurs réduites : Élimine les exceptions potentielles de KeyError
Plus lisible : Rend la logique de comptage plus claire et plus concise
Le defaultdict avec une valeur par défaut de 0 est particulièrement utile pour toute tâche impliquant le comptage ou l'accumulation de valeurs, telles que :
Analyse de fréquence
Histogrammes
Agrégation de données par catégories
Suivi des occurrences dans des journaux ou des ensembles de données
Comparaison des performances : defaultdict vs. dictionnaire classique
Comparons les performances d'un defaultdict avec une valeur par défaut de 0 et d'un dictionnaire classique pour une tâche de comptage commune. Cela vous aidera à comprendre quand choisir l'un plutôt que l'autre.
Créez un nouveau fichier appelé performance_comparison.py dans l'éditeur :
import time
from collections import defaultdict
def count_with_regular_dict(data):
"""Compte les fréquences en utilisant un dictionnaire classique."""
counts = {}
for item in data:
if item in counts:
counts[item] += 1
else:
counts[item] = 1
return counts
def count_with_defaultdict(data):
"""Compte les fréquences en utilisant un defaultdict avec une valeur par défaut de 0."""
counts = defaultdict(int)
for item in data:
counts[item] += 1
return counts
## Génère des données de test - une liste de nombres aléatoires entre 0 et 99
import random
random.seed(42) ## Pour des résultats reproductibles
data = [random.randint(0, 99) for _ in range(1000000)]
## Mesure le temps de l'approche avec le dictionnaire classique
start_time = time.time()
result1 = count_with_regular_dict(data)
regular_dict_time = time.time() - start_time
## Mesure le temps de l'approche avec le defaultdict
start_time = time.time()
result2 = count_with_defaultdict(data)
defaultdict_time = time.time() - start_time
## Affiche les résultats
print(f"Temps du dictionnaire classique : {regular_dict_time:.4f} secondes")
print(f"Temps du defaultdict : {defaultdict_time:.4f} secondes")
print(f"Le defaultdict est {regular_dict_time/defaultdict_time:.2f} fois plus rapide")
## Vérifie que les deux méthodes donnent les mêmes résultats
assert dict(result2) == result1, "Les résultats de comptage ne correspondent pas!"
print("\nLes deux méthodes ont produit les mêmes comptes ✓")
## Affiche un échantillonnage des comptes
print("\nÉchantillonnage des comptes (les 5 premiers éléments) :")
for i, (key, value) in enumerate(sorted(result1.items())):
if i >= 5:
break
print(f" Nombre {key}: {value} occurrences")
Exécutez le script à partir du terminal :
python3 performance_comparison.py
Vous devriez voir une sortie similaire à :
Temps du dictionnaire classique : 0.1075 secondes
Temps du defaultdict : 0.0963 secondes
Le defaultdict est 1.12 fois plus rapide
Les deux méthodes ont produit les mêmes comptes ✓
Échantillonnage des comptes (les 5 premiers éléments) :
Nombre 0: 10192 occurrences
Nombre 1: 9949 occurrences
Nombre 2: 9929 occurrences
Nombre 3: 9881 occurrences
Nombre 4: 9922 occurrences
Remarque : Vos résultats de mesure exacts peuvent varier selon votre système.
Analyse des résultats
La comparaison des performances montre que le defaultdict est généralement plus rapide que les dictionnaires classiques pour les tâches de comptage car :
Il élimine la nécessité de vérifier l'existence des clés (if key in dictionary)
Il réduit le nombre de recherches dans le dictionnaire par élément
Il simplifie le code, ce qui peut entraîner des optimisations par l'interpréteur Python
En plus des avantages de performance, le defaultdict offre ces avantages :
Simplicité du code : Le code est plus concis et lisible
Charge cognitive réduite : Vous n'avez pas besoin de vous souvenir de gérer le cas des clés manquantes
Moindres chances d'erreurs : Moins de code signifie moins de chances d'erreurs
Cela rend le defaultdict avec une valeur par défaut de 0 un excellent choix pour les opérations de comptage, l'analyse de fréquence et autres tâches d'accumulation en Python.
Récapitulatif
Dans ce laboratoire, vous avez appris à utiliser le defaultdict de Python et à l'utiliser avec une valeur par défaut de 0. Revoyons ce que nous avons vu :
Nous avons identifié la limitation des dictionnaires classiques qui lève une KeyError lors de l'accès à des clés inexistantes
Nous avons appris à créer un defaultdict avec une valeur par défaut de 0 en utilisant à la fois defaultdict(int) et defaultdict(lambda: 0)
Nous avons exploré un cas d'utilisation pratique en implémentant un compteur de fréquences de mots
Nous avons comparé les performances de defaultdict et de dictionnaires classiques et avons vu que defaultdict est non seulement plus pratique mais également plus rapide pour les tâches de comptage
Le defaultdict avec une valeur par défaut de 0 est un outil puissant qui simplifie le comptage, l'accumulation et l'analyse de fréquence en Python. En gérant automatiquement les clés manquantes, il rend votre code plus propre, plus efficace et moins sujet à des erreurs.
Ce modèle est couramment utilisé dans :
Le traitement et l'analyse de données
Le traitement du langage naturel
L'analyse des journaux
Le développement de jeux (pour les systèmes de notation)
N'importe quel scénario impliquant des compteurs ou des accumulateurs
En maîtrisant le defaultdict avec une valeur par défaut de 0, vous avez ajouté un outil important à votre outil de programmation Python qui vous aidera à écrire du code plus élégant et efficace.