
Vous avez une liste de 1000 utilisateurs et vous cherchez celui dont l'email est "alice.durand@laposte.net". Avec une liste classique, vous devez parcourir chaque élément un par un. Avec un dictionnaire, l'accès est instantané : users["alice.durand@laposte.net"].
Un dictionnaire Python (type dict) est une structure de données qui stocke des paires clé-valeur, créée avec des accolades : utilisateur = {'nom': 'Alice', 'age': 30}. Contrairement aux listes où vous accédez aux éléments par leur position (index 0, 1, 2...), les dictionnaires vous permettent d'accéder aux données par un nom significatif : utilisateur['nom']. C'est la structure idéale pour représenter des objets du monde réel : un utilisateur avec son nom, email et âge ; une configuration avec ses paramètres ; ou une réponse d'API au format JSON.
Ce guide vous accompagne de la création de votre premier dictionnaire jusqu'aux techniques avancées comme les compréhensions et les structures imbriquées.
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »Ce guide couvre l'essentiel des dictionnaires Python, de la création à l'utilisation avancée. Chaque section est accompagnée d'exemples concrets que vous pouvez copier et tester immédiatement.
À la fin de ce guide, vous saurez :
- Créer des dictionnaires vides ou pré-remplis, la base pour stocker vos données structurées
- Accéder aux valeurs de manière sécurisée avec
get(), éviter les crashs sur des clés manquantes - Ajouter, modifier et supprimer des éléments, les opérations CRUD quotidiennes
- Parcourir les clés, valeurs ou les deux ensemble, traiter vos données efficacement
- Transformer des données avec les compréhensions de dictionnaire, écrire du code concis et pythonique
- Gérer des structures imbriquées (dictionnaires dans des dictionnaires), manipuler des données JSON et API
- Appliquer les bonnes pratiques pour un code robuste, éviter les pièges classiques
Qu'est-ce qu'un dictionnaire Python ?
Section intitulée « Qu'est-ce qu'un dictionnaire Python ? »La structure clé-valeur
Section intitulée « La structure clé-valeur »Un dictionnaire est une collection non ordonnée (depuis Python 3.7, l'ordre d'insertion est préservé) de paires clé-valeur. Chaque clé est unique et pointe vers une valeur.
# Un dictionnaire simplepersonne = { "nom": "Alice", "age": 30, "ville": "Paris"}Chaque dictionnaire se compose de trois éléments fondamentaux que vous manipulerez constamment :
| Élément | Description | Exemple |
|---|---|---|
| Clé | Identifiant unique (immuable) | "nom", "age", 42 |
| Valeur | Donnée associée (tout type) | "Alice", 30, [1, 2, 3] |
| Paire | Association clé → valeur | "nom": "Alice" |
La clé joue le rôle d'étiquette : elle doit être unique dans le dictionnaire (impossible d'avoir deux clés identiques) et immuable (les chaînes, nombres et tuples fonctionnent, mais pas les listes).
La valeur peut être de n'importe quel type Python : une chaîne, un nombre, une liste, un autre dictionnaire, ou même une fonction. Cette flexibilité fait des dictionnaires une structure de données extrêmement polyvalente.
La paire clé-valeur est la brique de base : vous écrivez clé: valeur séparées par deux-points, et chaque paire est séparée des autres par une virgule.
Pourquoi utiliser un dictionnaire ?
Section intitulée « Pourquoi utiliser un dictionnaire ? »Les listes et les dictionnaires sont les deux structures de données les plus utilisées en Python. Comprendre leurs différences vous permet de choisir la bonne structure selon votre besoin :
| Situation | Liste | Dictionnaire |
|---|---|---|
| Accéder par position | Oui : liste[0] | Non prévu pour ça |
| Accéder par nom/identifiant | Non : parcours nécessaire | Oui : dict["nom"] |
| Stocker des données hétérogènes nommées | Peu lisible | Idéal |
| Représenter un objet | Difficile | Naturel |
| Performance d'accès | O(n) | O(1) en moyenne |
Concrètement, voici comment ces différences se manifestent dans le code :
-
Accès par position vs par nom : avec une liste
["Alice", 30, "Paris"], vous devez vous souvenir que l'index 1 correspond à l'âge. Avec un dictionnaire,utilisateur["age"]est explicite. -
Performance : pour une liste de 10 000 éléments, trouver une valeur peut nécessiter de parcourir les 10 000 éléments (complexité O(n)). Un dictionnaire accède directement à la valeur via sa clé, quelle que soit la taille (complexité O(1)).
-
Données hétérogènes : un dictionnaire exprime naturellement qu'un utilisateur a un nom (texte), un âge (nombre) et un statut actif (booléen). Une liste mélange ces types sans contexte.
Créer un dictionnaire
Section intitulée « Créer un dictionnaire »Syntaxe avec accolades (recommandée)
Section intitulée « Syntaxe avec accolades (recommandée) »La méthode la plus courante et la plus lisible utilise des accolades {} : vous listez les paires clé: valeur séparées par des virgules.
# Dictionnaire videconfig = {}
# Dictionnaire avec des donnéesutilisateur = { "nom": "Alice", "email": "alice.durand@laposte.net", "age": 30, "actif": True}Syntaxe avec dict()
Section intitulée « Syntaxe avec dict() »Le constructeur dict() crée un dictionnaire à partir d'arguments nommés, d'une liste de tuples, ou de deux séquences combinées avec zip(). Pratique quand les données viennent déjà sous forme de paires.
# À partir de mots-clésutilisateur = dict(nom="Alice", email="alice.durand@laposte.net", age=30)
# À partir de tuplesutilisateur = dict([("nom", "Alice"), ("email", "alice.durand@laposte.net")])
# À partir de deux listes avec zip()cles = ["nom", "email", "age"]valeurs = ["Alice", "alice.durand@laposte.net", 30]utilisateur = dict(zip(cles, valeurs))Types de clés autorisés
Section intitulée « Types de clés autorisés »Les clés doivent être immuables (non modifiables). Pourquoi cette contrainte ? Python utilise un mécanisme appelé hachage pour retrouver instantanément une valeur à partir de sa clé. Si la clé pouvait changer après son insertion, Python ne saurait plus où retrouver la valeur associée.
Types immuables utilisables comme clés :
# Clés validesvalide = { "texte": "valeur", # str - le plus courant 42: "valeur", # int - utile pour les ID numériques 3.14: "valeur", # float - rare mais possible (1, 2): "valeur", # tuple - utile pour les coordonnées True: "valeur" # bool - peu recommandé (collision avec 1)}Types mutables interdits :
# Clés invalides (TypeError: unhashable type)# invalide = {# [1, 2]: "valeur", # liste → utilisez un tuple (1, 2)# {"a": 1}: "valeur" # dict → utilisez un tuple de tuples# }Accéder aux valeurs
Section intitulée « Accéder aux valeurs »Accès direct avec []
Section intitulée « Accès direct avec [] »L'accès direct par crochets renvoie la valeur associée à une clé. C'est la syntaxe la plus rapide, mais elle lève une KeyError si la clé est absente.
utilisateur = {"nom": "Alice", "age": 30}
# Accès simplenom = utilisateur["nom"]print(nom) # Alice
# Erreur si la clé n'existe pas# ville = utilisateur["ville"] # KeyError: 'ville'Accès sécurisé avec get()
Section intitulée « Accès sécurisé avec get() »La méthode get() évite les erreurs KeyError :
utilisateur = {"nom": "Alice", "age": 30}
# Retourne None si la clé n'existe pasville = utilisateur.get("ville")print(ville) # None
# Retourne une valeur par défautville = utilisateur.get("ville", "Non renseignée")print(ville) # Non renseignée
# La clé existe : retourne sa valeurnom = utilisateur.get("nom", "Inconnu")print(nom) # AliceVérifier l'existence d'une clé
Section intitulée « Vérifier l'existence d'une clé »L'opérateur in teste si une clé est présente avant d'y accéder ou d'en ajouter une, ce qui évite les erreurs et les écrasements involontaires.
utilisateur = {"nom": "Alice", "age": 30}
# Avec 'in'if "email" in utilisateur: print(utilisateur["email"])else: print("Email non renseigné")
# Avec 'not in'if "ville" not in utilisateur: utilisateur["ville"] = "Paris"Modifier un dictionnaire
Section intitulée « Modifier un dictionnaire »Une fois le dictionnaire créé, vous ajoutez, modifiez ou supprimez des éléments à tout moment : un dictionnaire est mutable. Les opérations ci-dessous couvrent les cas les plus fréquents, de l'ajout d'une clé unique à la mise à jour groupée.
Ajouter une clé à un dictionnaire
Section intitulée « Ajouter une clé à un dictionnaire »Pour ajouter une clé, affectez-lui une valeur : si la clé n'existe pas, elle est créée ; si elle existe déjà, sa valeur est remplacée.
utilisateur = {"nom": "Alice"}
# Ajouter une nouvelle cléutilisateur["email"] = "alice.durand@laposte.net"print(utilisateur) # {'nom': 'Alice', 'email': 'alice.durand@laposte.net'}
# Modifier une clé existanteutilisateur["email"] = "alice.durand.pro@laposte.net"print(utilisateur) # {'nom': 'Alice', 'email': 'alice.durand.pro@laposte.net'}Ajouter plusieurs éléments avec update()
Section intitulée « Ajouter plusieurs éléments avec update() »La méthode update() ajoute ou met à jour plusieurs clés en une seule opération, à partir d'un autre dictionnaire. Les clés déjà présentes sont écrasées.
utilisateur = {"nom": "Alice"}
# Ajouter plusieurs clésutilisateur.update({ "email": "alice.durand@laposte.net", "age": 30, "ville": "Paris"})print(utilisateur)# {'nom': 'Alice', 'email': 'alice.durand@laposte.net', 'age': 30, 'ville': 'Paris'}
# update() écrase les valeurs existantesutilisateur.update({"age": 31})print(utilisateur["age"]) # 31Définir une valeur par défaut avec setdefault()
Section intitulée « Définir une valeur par défaut avec setdefault() »setdefault() ajoute une clé seulement si elle n'existe pas :
utilisateur = {"nom": "Alice"}
# La clé n'existe pas → elle est ajoutéeutilisateur.setdefault("ville", "Paris")print(utilisateur) # {'nom': 'Alice', 'ville': 'Paris'}
# La clé existe déjà → rien ne changeutilisateur.setdefault("ville", "Lyon")print(utilisateur) # {'nom': 'Alice', 'ville': 'Paris'}Supprimer des éléments
Section intitulée « Supprimer des éléments »Supprimer et récupérer avec pop()
Section intitulée « Supprimer et récupérer avec pop() »La méthode pop() supprime une clé et retourne sa valeur, ce qui permet de la récupérer au passage. Un second argument sert de valeur de repli si la clé est absente, pour éviter la KeyError.
utilisateur = {"nom": "Alice", "email": "alice.durand@laposte.net", "age": 30}
# Supprimer et récupérer la valeuremail = utilisateur.pop("email")print(email) # alice.durand@laposte.netprint(utilisateur) # {'nom': 'Alice', 'age': 30}
# Valeur par défaut si la clé n'existe pasville = utilisateur.pop("ville", "Aucune")print(ville) # Aucune (pas d'erreur)Supprimer avec del
Section intitulée « Supprimer avec del »L'instruction del supprime une clé sans renvoyer sa valeur. Elle lève une KeyError si la clé n'existe pas : utilisez-la quand vous êtes sûr de sa présence.
utilisateur = {"nom": "Alice", "email": "alice.durand@laposte.net"}
# Supprimer une clédel utilisateur["email"]print(utilisateur) # {'nom': 'Alice'}
# Erreur si la clé n'existe pas# del utilisateur["ville"] # KeyErrorSupprimer le dernier élément avec popitem()
Section intitulée « Supprimer le dernier élément avec popitem() »La méthode popitem() retire et retourne la dernière paire insérée, sous forme de tuple (clé, valeur). Utile pour vider un dictionnaire comme une pile (dernier entré, premier sorti).
utilisateur = {"nom": "Alice", "email": "alice.durand@laposte.net", "age": 30}
# Supprime et retourne la dernière paire ajoutéederniere = utilisateur.popitem()print(derniere) # ('age', 30)print(utilisateur) # {'nom': 'Alice', 'email': 'alice.durand@laposte.net'}Vider le dictionnaire avec clear()
Section intitulée « Vider le dictionnaire avec clear() »La méthode clear() retire toutes les clés d'un coup tout en conservant le même objet en mémoire. Les autres variables qui référencent ce dictionnaire voient donc aussi le vidage.
utilisateur = {"nom": "Alice", "age": 30}
utilisateur.clear()print(utilisateur) # {}Parcourir un dictionnaire
Section intitulée « Parcourir un dictionnaire »Contrairement aux listes où vous parcourez simplement les éléments dans l'ordre, un dictionnaire offre trois façons de le parcourir selon ce dont vous avez besoin : les clés seules, les valeurs seules, ou les deux ensemble. Choisir la bonne méthode rend votre code plus clair et plus efficace.
Parcourir les clés
Section intitulée « Parcourir les clés »Quand vous avez besoin uniquement des identifiants (par exemple, pour vérifier quelles clés existent ou pour construire une liste de noms de champs) :
utilisateur = {"nom": "Alice", "age": 30, "ville": "Paris"}
# Par défaut, itérer sur un dict parcourt ses clésfor cle in utilisateur: print(cle)# nom# age# ville
# Explicitement avec keys() - même résultat, intention plus clairefor cle in utilisateur.keys(): print(cle)Cas d'usage : lister les champs d'une configuration, vérifier la présence de certaines clés, générer des rapports sur la structure des données.
Parcourir les valeurs
Section intitulée « Parcourir les valeurs »Quand vous n'avez pas besoin de savoir d'où vient chaque valeur (par exemple, pour calculer une somme ou trouver un maximum) :
utilisateur = {"nom": "Alice", "age": 30, "ville": "Paris"}
for valeur in utilisateur.values(): print(valeur)# Alice# 30# ParisCas d'usage : calculer la somme des valeurs numériques, compter les occurrences, vérifier si une valeur particulière existe.
# Exemple pratique : calculer le total des scoresscores = {"Alice": 85, "Bob": 92, "Charlie": 78}total = sum(scores.values())print(f"Total: {total}") # Total: 255Parcourir les paires clé-valeur (recommandé)
Section intitulée « Parcourir les paires clé-valeur (recommandé) »C'est la méthode la plus courante car vous avez généralement besoin de contexte (la clé) pour traiter chaque valeur :
utilisateur = {"nom": "Alice", "age": 30, "ville": "Paris"}
for cle, valeur in utilisateur.items(): print(f"{cle}: {valeur}")# nom: Alice# age: 30# ville: ParisCas d'usage : afficher un rapport formaté, transformer les données, filtrer selon des critères, exporter vers un autre format.
# Exemple pratique : formater pour l'affichageconfig = {"host": "localhost", "port": 5432, "debug": True}print("Configuration:")for param, valeur in config.items(): print(f" • {param} = {valeur}")Compréhensions de dictionnaire
Section intitulée « Compréhensions de dictionnaire »Les compréhensions permettent de créer des dictionnaires de manière concise et expressive. C'est l'une des fonctionnalités les plus élégantes de Python : une seule ligne remplace souvent 4-5 lignes de boucle.
Syntaxe de base
Section intitulée « Syntaxe de base »La syntaxe suit le pattern {clé: valeur for élément in iterable}. Lisez-la de droite à gauche : "pour chaque élément dans l'iterable, crée une paire clé-valeur".
# Version longue avec bouclecarres = {}for x in range(1, 6): carres[x] = x**2
# Version compréhension (équivalente)carres = {x: x**2 for x in range(1, 6)}print(carres) # {1: 1, 2: 4, 3: 9, 4: 16, 5: 25}Décomposition : {x: x**2 for x in range(1, 6)}
for x in range(1, 6)→ parcourt les nombres 1, 2, 3, 4, 5x: x**2→ pour chaque x, crée la paire (x, x²){}→ le tout dans un dictionnaire
Avec condition
Section intitulée « Avec condition »Une condition if placée en fin de compréhension agit comme un filtre : seuls les éléments qui la satisfont produisent une paire dans le dictionnaire final.
# Garder seulement les nombres pairscarres_pairs = {x: x**2 for x in range(1, 11) if x % 2 == 0}print(carres_pairs) # {2: 4, 4: 16, 6: 36, 8: 64, 10: 100}Transformer un dictionnaire existant
Section intitulée « Transformer un dictionnaire existant »Une compréhension qui itère sur items() applique un calcul à chaque valeur (ou clé) pour produire un nouveau dictionnaire, sans modifier l'original.
prix_euros = {"pomme": 1.5, "banane": 0.8, "orange": 2.0}
# Convertir en dollars (taux 1.1)prix_dollars = {fruit: prix * 1.1 for fruit, prix in prix_euros.items()}print(prix_dollars) # {'pomme': 1.65, 'banane': 0.88, 'orange': 2.2}
# Filtrer les produits chersproduits_chers = {f: p for f, p in prix_euros.items() if p >= 1.5}print(produits_chers) # {'pomme': 1.5, 'orange': 2.0}Inverser clés et valeurs
Section intitulée « Inverser clés et valeurs »En échangeant k et v dans la compréhension, vous inversez le dictionnaire (les valeurs deviennent des clés). Attention : des valeurs en double provoqueraient des collisions de clés.
original = {"a": 1, "b": 2, "c": 3}inverse = {v: k for k, v in original.items()}print(inverse) # {1: 'a', 2: 'b', 3: 'c'}Créer à partir de deux listes
Section intitulée « Créer à partir de deux listes »La fonction zip() associe deux listes position par position ; la compréhension transforme ensuite ces couples en paires clé-valeur.
noms = ["Alice", "Bob", "Charlie"]ages = [30, 25, 35]
# Avec zip() et compréhensionpersonnes = {nom: age for nom, age in zip(noms, ages)}print(personnes) # {'Alice': 30, 'Bob': 25, 'Charlie': 35}Dictionnaires imbriqués
Section intitulée « Dictionnaires imbriqués »Les dictionnaires peuvent contenir d'autres dictionnaires, ce qui permet de représenter des structures de données complexes. C'est exactement ce que vous recevez quand vous interrogez une API REST ou lisez un fichier JSON.
Cas d'usage typiques
Section intitulée « Cas d'usage typiques »- Réponses d'API :
{"status": "ok", "data": {"user": {...}, "permissions": [...]}} - Configuration :
{"database": {"host": "...", "port": 5432}, "cache": {...}} - Données relationnelles : employés par département, produits par catégorie
Création et accès
Section intitulée « Création et accès »Voici un exemple concret : une base de données d'employés où chaque ID pointe vers les informations de l'employé.
employes = { "E001": { "nom": "Alice", "poste": "Développeuse", "salaire": 45000 }, "E002": { "nom": "Bob", "poste": "Designer", "salaire": 40000 }}
# Accéder à une valeur imbriquéeprint(employes["E001"]["nom"]) # Aliceprint(employes["E002"]["salaire"]) # 40000Modifier un élément imbriqué
Section intitulée « Modifier un élément imbriqué »Pour modifier une valeur profonde, chaînez les crochets jusqu'au niveau voulu. Une affectation sur une clé absente à ce niveau la crée au passage.
# Augmenter le salaire d'Aliceemployes["E001"]["salaire"] = 48000
# Ajouter un nouvel attributemployes["E001"]["departement"] = "IT"Parcourir un dictionnaire imbriqué
Section intitulée « Parcourir un dictionnaire imbriqué »Deux boucles imbriquées suffisent : la première parcourt chaque enregistrement, la seconde ses attributs internes.
for id_employe, infos in employes.items(): print(f"\n{id_employe}:") for attribut, valeur in infos.items(): print(f" {attribut}: {valeur}")
# E001:# nom: Alice# poste: Développeuse# salaire: 48000# departement: IT# E002:# nom: Bob# poste: Designer# salaire: 40000Accès sécurisé aux structures imbriquées
Section intitulée « Accès sécurisé aux structures imbriquées »Enchaîner des get() avec un dictionnaire vide {} comme valeur par défaut évite la KeyError lorsqu'un niveau intermédiaire est absent.
# Risqué si une clé intermédiaire n'existe pas# ville = employes["E003"]["adresse"]["ville"] # KeyError
# Accès sécurisé chaînéemploye = employes.get("E003", {})adresse = employe.get("adresse", {})ville = adresse.get("ville", "Non renseignée")print(ville) # Non renseignéeFusionner des dictionnaires
Section intitulée « Fusionner des dictionnaires »Fusionner des dictionnaires est une opération courante : combiner des configurations par défaut avec des options utilisateur, enrichir des données avec des informations complémentaires, ou consolider des résultats partiels.
Python propose trois syntaxes selon vos besoins.
Avec update() (modifie en place)
Section intitulée « Avec update() (modifie en place) »Utilisez update() quand vous voulez modifier le dictionnaire original. C'est efficace en mémoire pour les gros dictionnaires.
base = {"nom": "Alice", "age": 30}extra = {"ville": "Paris", "age": 31}
base.update(extra)print(base) # {'nom': 'Alice', 'age': 31, 'ville': 'Paris'}# Attention : 'age' est écrasé par la valeur de 'extra'Cas d'usage : appliquer des options utilisateur sur une configuration par défaut.
Avec l'opérateur ** (crée un nouveau dict)
Section intitulée « Avec l'opérateur ** (crée un nouveau dict) »Le dépaquetage ** rassemble plusieurs dictionnaires dans un nouveau dictionnaire, sans modifier les originaux. Compatible avec toutes les versions de Python 3.
base = {"nom": "Alice", "age": 30}extra = {"ville": "Paris", "email": "alice.durand@laposte.net"}
fusionne = {**base, **extra}print(fusionne)# {'nom': 'Alice', 'age': 30, 'ville': 'Paris', 'email': 'alice.durand@laposte.net'}
# Les dicts originaux ne sont pas modifiésprint(base) # {'nom': 'Alice', 'age': 30}Avec l'opérateur | (Python 3.9+)
Section intitulée « Avec l'opérateur | (Python 3.9+) »Depuis Python 3.9, l'opérateur | fusionne deux dictionnaires en un nouveau, et |= réalise la fusion en place. C'est la syntaxe la plus lisible quand elle est disponible.
base = {"nom": "Alice", "age": 30}extra = {"ville": "Paris"}
# Union (nouveau dictionnaire)fusionne = base | extraprint(fusionne) # {'nom': 'Alice', 'age': 30, 'ville': 'Paris'}
# Union en placebase |= extraprint(base) # {'nom': 'Alice', 'age': 30, 'ville': 'Paris'}Méthodes essentielles : récapitulatif
Section intitulée « Méthodes essentielles : récapitulatif »Voici les 10 méthodes que vous utiliserez le plus souvent. Gardez ce tableau sous le coude comme référence rapide :
| Méthode | Description | Exemple |
|---|---|---|
get(clé, défaut) | Accès sécurisé | d.get("x", 0) |
keys() | Vue des clés | for k in d.keys() |
values() | Vue des valeurs | for v in d.values() |
items() | Vue des paires | for k, v in d.items() |
pop(clé, défaut) | Supprime et retourne | d.pop("x", None) |
popitem() | Supprime la dernière paire | d.popitem() |
update(autre) | Fusionne | d.update({"a": 1}) |
setdefault(clé, val) | Ajoute si absent | d.setdefault("x", 0) |
clear() | Vide le dict | d.clear() |
copy() | Copie superficielle | d2 = d.copy() |
Les plus utilisées au quotidien :
-
get(): indispensable pour éviter les crashs quand vous traitez des données externes (API, fichiers JSON, formulaires). Toujours préférerd.get("clé", valeur_defaut)àd["clé"]quand la clé peut être absente. -
items(): la méthode de parcours standard. Dans 90% des cas où vous parcourez un dictionnaire, vous avez besoin à la fois de la clé et de la valeur. -
update(): parfait pour fusionner des configurations ou enrichir des données. Attention : les clés existantes sont écrasées par les nouvelles valeurs. -
pop(): utile pour extraire une valeur tout en la supprimant du dictionnaire (pattern courant dans les files de traitement).
Bonnes pratiques
Section intitulée « Bonnes pratiques »Ces recommandations viennent de l'expérience collective de la communauté Python. Elles vous éviteront des bugs subtils et rendront votre code plus facile à maintenir.
1. Utilisez des clés descriptives
Section intitulée « 1. Utilisez des clés descriptives »Les abréviations font gagner quelques caractères mais rendent le code obscur. Dans 6 mois, vous ne vous souviendrez plus ce que signifie "n" ou "a".
# Peu lisible - économie de caractères mal placéeu = {"n": "Alice", "a": 30, "e": "alice.durand@laposte.net"}
# Clair et maintenable - le code se lit comme de la proseutilisateur = {"nom": "Alice", "age": 30, "email": "alice.durand@laposte.net"}Astuce : utilisez des noms qui répondent à la question "qu'est-ce que cette valeur représente ?" plutôt que des raccourcis cryptiques.
2. Préférez get() pour les données externes
Section intitulée « 2. Préférez get() pour les données externes »Avec des données venues d'une API, d'un fichier ou d'un formulaire, une clé peut manquer sans que ce soit un bug. get() renvoie alors une valeur de repli plutôt que de faire planter le programme.
# Données venant d'une API ou d'un fichierreponse = {"status": "ok", "data": {"user": "Alice"}}
# Robuste face aux champs manquantsuser = reponse.get("data", {}).get("user", "Inconnu")3. Ne modifiez pas un dict pendant son parcours
Section intitulée « 3. Ne modifiez pas un dict pendant son parcours »Supprimer ou ajouter des clés pendant l'itération change la taille du dictionnaire en cours de route et déclenche une RuntimeError. Itérez plutôt sur une copie des clés.
scores = {"Alice": 10, "Bob": 5, "Charlie": 15}
# Dangereux : RuntimeError possible# for nom in scores:# if scores[nom] < 10:# del scores[nom]
# Créez une copie ou une liste des clésfor nom in list(scores.keys()): if scores[nom] < 10: del scores[nom]4. Utilisez les compréhensions pour les transformations simples
Section intitulée « 4. Utilisez les compréhensions pour les transformations simples »Pour une transformation directe, une compréhension remplace une boucle de plusieurs lignes par une seule expression lisible. Réservez la boucle classique aux logiques complexes.
# Verbeuxresultat = {}for x in range(5): resultat[x] = x ** 2
# Concis et expressifresultat = {x: x**2 for x in range(5)}5. Évitez l'imbrication excessive
Section intitulée « 5. Évitez l'imbrication excessive »Au-delà de deux ou trois niveaux, un dictionnaire imbriqué devient difficile à lire et à maintenir. Une dataclass ou une structure aplatie exprime souvent mieux l'intention.
# Difficile à maintenirdata = { "niveau1": { "niveau2": { "niveau3": { "valeur": 42 } } }}
# Envisagez des classes ou aplatissez la structurefrom dataclasses import dataclass
@dataclassclass Config: valeur: int = 42Exercice pratique : gestion de contacts
Section intitulée « Exercice pratique : gestion de contacts »Créez un programme de gestion de contacts avec les fonctionnalités suivantes :
- Créer un dictionnaire de contacts (nom → infos)
- Ajouter un nouveau contact avec email et téléphone
- Rechercher un contact par nom
- Modifier le téléphone d'un contact
- Supprimer un contact
- Lister tous les contacts
Structure attendue :
contacts = { "Alice": {"email": "alice.durand@laposte.net", "tel": "0612345678"}, "Bob": {"email": "bob.lemaire@orange.fr", "tel": "0698765432"}}# 1. Dictionnaire initialcontacts = { "Alice": {"email": "alice.durand@laposte.net", "tel": "0612345678"}, "Bob": {"email": "bob.lemaire@orange.fr", "tel": "0698765432"}}
# 2. Fonction pour ajouter un contactdef ajouter_contact(nom, email, tel): if nom in contacts: print(f"Le contact {nom} existe déjà.") return False contacts[nom] = {"email": email, "tel": tel} print(f"Contact {nom} ajouté.") return True
# 3. Fonction pour rechercher un contactdef rechercher_contact(nom): contact = contacts.get(nom) if contact: print(f"{nom}:") print(f" Email: {contact['email']}") print(f" Tél: {contact['tel']}") return contact print(f"Contact {nom} non trouvé.") return None
# 4. Fonction pour modifier le téléphonedef modifier_telephone(nom, nouveau_tel): if nom in contacts: contacts[nom]["tel"] = nouveau_tel print(f"Téléphone de {nom} mis à jour.") return True print(f"Contact {nom} non trouvé.") return False
# 5. Fonction pour supprimer un contactdef supprimer_contact(nom): contact = contacts.pop(nom, None) if contact: print(f"Contact {nom} supprimé.") return True print(f"Contact {nom} non trouvé.") return False
# 6. Fonction pour lister tous les contactsdef lister_contacts(): if not contacts: print("Aucun contact.") return print(f"\n{'='*40}") print(f"{'NOM':<15} {'EMAIL':<25} {'TÉL'}") print(f"{'='*40}") for nom, infos in contacts.items(): print(f"{nom:<15} {infos['email']:<25} {infos['tel']}") print(f"{'='*40}") print(f"Total: {len(contacts)} contact(s)")
# Testsprint("=== AJOUT ===")ajouter_contact("Charlie", "charlie.moreau@free.fr", "0611223344")
print("\n=== RECHERCHE ===")rechercher_contact("Alice")rechercher_contact("David")
print("\n=== MODIFICATION ===")modifier_telephone("Bob", "0699999999")
print("\n=== LISTE ===")lister_contacts()
print("\n=== SUPPRESSION ===")supprimer_contact("Bob")
print("\n=== LISTE FINALE ===")lister_contacts()Dépannage des erreurs courantes
Section intitulée « Dépannage des erreurs courantes »Voici les trois erreurs que tout développeur Python rencontre avec les dictionnaires. Comprendre leur cause permet de les éviter systématiquement.
KeyError : clé inexistante
Section intitulée « KeyError : clé inexistante »C'est l'erreur la plus fréquente. Elle survient quand vous essayez d'accéder à une clé qui n'existe pas avec la syntaxe dict[clé].
Quand ça arrive : typiquement avec des données externes (réponse API, fichier JSON) où certains champs peuvent être absents.
d = {"nom": "Alice"}
# Erreur - la clé "age" n'existe pas# print(d["age"]) # KeyError: 'age'
# Solution 1 : get() avec valeur par défautprint(d.get("age")) # None (pas d'erreur)print(d.get("age", 0)) # 0 (valeur par défaut)
# Solution 2 : vérifier l'existence avant d'accéderif "age" in d: print(d["age"])else: print("Âge non renseigné")Règle : utilisez get() par défaut, réservez [] aux cas où l'absence de clé est une erreur de logique que vous voulez détecter.
TypeError : clé non hashable
Section intitulée « TypeError : clé non hashable »Une clé doit être hashable, donc immuable. Utiliser une liste ou un dictionnaire comme clé déclenche une TypeError : remplacez-les par un tuple.
# Les listes ne peuvent pas être des clés# d = {[1, 2]: "valeur"} # TypeError: unhashable type: 'list'
# Utilisez un tupled = {(1, 2): "valeur"}Modification pendant le parcours
Section intitulée « Modification pendant le parcours »Modifier la taille d'un dictionnaire pendant qu'on le parcourt lève une RuntimeError. La parade est simple : parcourez une copie des clés avec list(d.keys()).
d = {"a": 1, "b": 2, "c": 3}
# RuntimeError possible# for k in d:# del d[k]
# Parcourez une copiefor k in list(d.keys()): del d[k]Contrôle de connaissances
Section intitulée « Contrôle de connaissances »Vérifiez que l'essentiel de ce guide est acquis. Les questions portent uniquement sur ce qui vient d'être expliqué ici.
Contrôle de connaissances
Validez vos connaissances avec ce quiz interactif
Informations
- Le chronomètre démarre au clic sur Démarrer
- Questions à choix multiples, vrai/faux et réponses courtes
- Vous pouvez naviguer entre les questions
- Les résultats détaillés sont affichés à la fin
Lance le quiz et démarre le chronomètre
Vérification
(0/0)Profil de compétences
Quoi faire maintenant
Ressources pour progresser
Des indices pour retenter votre chance ?
Nouveau quiz complet avec des questions aléatoires
Retravailler uniquement les questions ratées
Retour à la liste des certifications
À retenir
Section intitulée « À retenir »Si vous ne retenez que six choses de ce guide, retenez celles-ci. Ces règles couvrent 90% des situations que vous rencontrerez avec les dictionnaires :
-
Dictionnaire = paires clé-valeur, accès par nom, pas par position. Idéal pour représenter des objets.
-
Clés uniques et immuables, utilisez des strings, int, tuple. Jamais de listes ou dicts comme clés.
-
get()pour l'accès sécurisé, évite lesKeyErrorquand la clé peut être absente. -
items()pour parcourir, donne accès à la clé ET la valeur en même temps. -
Compréhensions pour transformer,
{k: v*2 for k, v in d.items()}est plus concis qu'une boucle. -
Ne jamais modifier pendant le parcours, créez une copie des clés avec
list(d.keys()).
Checklist
Section intitulée « Checklist »Utilisez cette checklist pour valider votre maîtrise des dictionnaires. Cochez chaque point une fois que vous êtes capable de le faire sans consulter la documentation. Si un point vous bloque, revenez à la section correspondante du guide.
Ces compétences sont indispensables pour tout travail avec les dictionnaires :
- Créer un dictionnaire avec
{}oudict() - Accéder aux valeurs avec
[]etget() - Vérifier l'existence d'une clé avec
in - Ajouter et modifier des éléments
Opérations
Section intitulée « Opérations »Ces opérations reviennent constamment dans le code du quotidien :
- Supprimer avec
pop(),del,clear() - Parcourir avec
keys(),values(),items() - Fusionner avec
update()ou|
Ces techniques vous permettent d'écrire du code plus élégant et de gérer des données complexes :
- Utiliser les compréhensions de dictionnaire
- Gérer les structures imbriquées
- Accès sécurisé aux données imbriquées
FAQ : questions fréquentes
Section intitulée « FAQ : questions fréquentes »Les réponses courtes ci-dessous couvrent les questions les plus recherchées sur les dictionnaires Python. Chaque exemple est autonome et testé sur Python 3.12.
utilisateur = {'nom': 'Alice', 'age': 30, 'actif': True}
Autres méthodes :- Constructeur
dict():dict(nom='Alice', age=30)(clés = identifiants valides seulement) - Dictionnaire vide :
mon_dict = {}puismon_dict['nom'] = 'Alice' - À partir de deux listes :
dict(zip(cles, valeurs))
utilisateur = {'nom': 'Alice'}
utilisateur['email'] = 'alice@example.com' # ajoute la clé
Variantes utiles :- Plusieurs clés d'un coup avec
update():utilisateur.update({'age': 30, 'ville': 'Lyon'}) - Ajouter seulement si absente avec
setdefault():utilisateur.setdefault('actif', True)
items(), qui donne la clé et la valeur à chaque tour de boucle :utilisateur = {'nom': 'Alice', 'age': 30}
for cle, valeur in utilisateur.items():
print(f"{cle} : {valeur}")
Selon le besoin :- Clés seules :
for cle in utilisateur.keys()(oufor cle in utilisateur) - Valeurs seules :
for valeur in utilisateur.values()
list(utilisateur)) si vous devez supprimer des clés.dict est le nom du type Python, et dictionnaire est le mot courant pour le concept. Les deux désignent la même structure clé-valeur.mon_dict = {'a': 1}
print(type(mon_dict)) # <class 'dict'>
vide = dict() # dictionnaire vide, équivaut à {}
En pratique : on écrit dict pour le type et le constructeur, on dit dictionnaire en français pour parler de la structure.| crée un nouveau dictionnaire fusionné :defauts = {'theme': 'clair', 'langue': 'fr'}
choix = {'langue': 'en'}
fusion = defauts | choix # {'theme': 'clair', 'langue': 'en'}
Autres approches :- Avant 3.9 :
{**defauts, **choix}(crée aussi un nouveau dict) - En place :
defauts.update(choix)(modifiedefauts)
utilisateurs = [
{'nom': 'Alice', 'age': 30},
{'nom': 'Bob', 'age': 25},
]
for u in utilisateurs:
print(u['nom'], u['age'])
Pour filtrer ou transformer, combinez avec une compréhension de liste :noms = [u['nom'] for u in utilisateurs if u['age'] >= 18]
Pour aller plus loin
Section intitulée « Pour aller plus loin »- Fonctions Python : organisez votre code en fonctions réutilisables.
- Manipuler du JSON : réutiliser vos connaissances des dictionnaires pour manipuler des données JSON.