Cours Python · Module 2: Structures de données

Les dictionnaires - Cataloguer les découvertes

11 min de lecture
Dans cette leçon17

Bienvenue de retour ! Darwin ici, avec une autre leçon importante.

Dans la leçon précédente, tu as découvert les listes - des collections ordonnées comme des sentiers d'expédition. Mais parfois, tu as besoin de quelque chose de plus - une façon de cataloguer tes découvertes avec des informations supplémentaires. Dans la jungle, chaque espèce a sa fiche de données : habitat, taille, si elle est dangereuse. En Python, on utilise des dictionnaires pour cela.

Que sont les dictionnaires ?

Un dictionnaire est une collection de paires clé : valeur. Imagine un catalogue de découvertes où chaque espèce (clé) possède sa fiche d'informations (valeur).

1# Catalogue d'espèces - la clé est le nom, la valeur les détails
2species_info = {
3    "Python regius": "Royal python, 1-2m, harmless",
4    "Panthera leo": "Lion, 2-3m, very dangerous",
5    "Loxodonta africana": "African elephant, 3-4m, calm"
6}
7
8# Catalogue plus complexe
9detailed_catalog = {
10    "Python regius": {
11        "common_name": "Royal Python",
12        "length_m": 1.5,
13        "habitat": "jungle",
14        "dangerous": False
15    },
16    "Panthera leo": {
17        "common_name": "Lion",
18        "length_m": 2.5,
19        "habitat": "savanna",
20        "dangerous": True
21    }
22}

Caractéristiques clés des dictionnaires :

  • Paires clé-valeur - chaque clé mène à une valeur
  • Conservent l'ordre d'insertion (depuis Python 3.7), mais n'ont pas d'index - on accède à une valeur par sa clé
  • Les clés doivent être uniques et immuables (chaîne, int, tuple)
  • Les valeurs peuvent être n'importe quoi - même d'autres dictionnaires !
  • Mutables - ils peuvent être modifiés

Créer des dictionnaires

1# Dictionnaire vide - catalogue vierge
2empty_catalog = {}
3empty_dict = dict()
4
5# Dictionnaire avec des données
6explorer_data = {
7    "name": "Darwin",
8    "age": 35,
9    "profession": "Researcher",
10    "discoveries": 47
11}
12
13# Différents types de clés (mais les chaînes sont les plus courantes)
14mixed_keys = {
15    "name": "Python",
16    42: "Answer",
17    (10, 20): "Coordinates"
18}
19
20# Dictionnaires imbriqués
21expedition = {
22    "location": "Amazonia",
23    "team": {
24        "leader": "Darwin",
25        "count": 5
26    },
27    "equipment": ["Binoculars", "Map", "GPS"]
28}
29
30# Constructeur dict()
31from_pairs = dict([("A", 1), ("B", 2), ("C", 3)])
32with_kwargs = dict(name="Darwin", age=35, job="Explorer")

Accéder aux valeurs

1species = {
2    "Python regius": "Royal Python",
3    "Panthera leo": "Lion",
4    "Loxodonta africana": "Elephant"
5}
6
7# Accès par clé (crochets)
8python_name = species["Python regius"]  # "Royal Python"
9lion_name = species["Panthera leo"]     # "Lion"
10
11# KeyError si la clé n'existe pas !
12# wrong = species["Tyrannosaurus"]  # KeyError !
13
14# Accès sécurisé - get()
15python_name = species.get("Python regius")  # "Royal Python"
16trex = species.get("Tyrannosaurus")         # None
17trex = species.get("Tyrannosaurus", "Not found")  # "Not found"
18
19print(f"Python: {python_name}")

get() vs [] :

  • dict[key] - lève une KeyError si la clé est absente
  • dict.get(key) - renvoie None si la clé est absente
  • dict.get(key, default) - renvoie default si la clé est absente

Ajouter et modifier

1catalog = {
2    "Python regius": {"length": 1.5, "habitat": "jungle"}
3}
4
5# Ajouter une nouvelle entrée
6catalog["Panthera leo"] = {"length": 2.5, "habitat": "savanna"}
7
8# Modifier une entrée existante
9catalog["Python regius"]["length"] = 1.8
10
11# Ajouter via update() - dictionnaire ou paires clé-valeur
12catalog.update({"Loxodonta africana": {"length": 4.0, "habitat": "savanna"}})
13catalog.update(discovered_by="Darwin", year=2024)
14
15print(catalog)

Supprimer des éléments

1species = {
2    "Python": "Python",
3    "Leo": "Lion",
4    "Elephas": "Elephant",
5    "Giraffa": "Giraffe"
6}
7
8# del - supprime par clé
9del species["Giraffa"]
10
11# pop() - supprime et renvoie la valeur
12leo_value = species.pop("Leo")  # "Lion"
13print(leo_value)
14
15# pop() avec une valeur par défaut (si la clé n'existe pas)
16dino = species.pop("T-Rex", "Not found")  # "Not found"
17
18# popitem() - supprime et renvoie la DERNIÈRE paire (Python 3.7+)
19last_item = species.popitem()  # ("Elephas", "Elephant")
20
21# clear() - vide tout le dictionnaire
22species.clear()
23print(species)  # {}

Vérifier l'existence d'une clé

1catalog = {
2    "Python regius": "Python",
3    "Panthera leo": "Lion"
4}
5
6# in - vérifie si la clé existe
7if "Python regius" in catalog:
8    print("Python is in the catalog!")
9
10if "T-Rex" not in catalog:
11    print("T-Rex is not in the catalog")
12
13# Note : 'in' vérifie les CLÉS, pas les valeurs !
14print("Python" in catalog)  # False (c'est une valeur, pas une clé !)

Itérer à travers un dictionnaire

1species = {
2    "Python regius": "Royal Python",
3    "Panthera leo": "Lion",
4    "Loxodonta africana": "African Elephant"
5}
6
7# Itérer sur les clés (par défaut)
8for species_name in species:
9    print(species_name)
10
11# Explicitement sur les clés - keys()
12for key in species.keys():
13    print(key)
14
15# Itérer sur les valeurs - values()
16for common_name in species.values():
17    print(common_name)
18
19# Itérer sur les paires clé-valeur - items() (le plus courant !)
20for species_name, common_name in species.items():
21    print(f"{species_name}: {common_name}")
22
23# Enumerate pour numéroter
24for i, (key, value) in enumerate(species.items(), start=1):
25    print(f"{i}. {key} -> {value}")

Méthodes de dictionnaire

keys(), values(), items()

1catalog = {
2    "Python": {"habitat": "jungle", "size": 1.5},
3    "Leo": {"habitat": "savanna", "size": 2.5}
4}
5
6# Toutes les clés
7all_keys = catalog.keys()  # dict_keys(['Python', 'Leo'])
8keys_list = list(catalog.keys())  # Liste : ['Python', 'Leo']
9
10# Toutes les valeurs
11all_values = catalog.values()  # dict_values([{...}, {...}])
12
13# Toutes les paires
14all_items = catalog.items()  # dict_items([('Python', {...}), ('Leo', {...})])
15
16# Conversion en listes
17keys = list(catalog.keys())
18values = list(catalog.values())
19items = list(catalog.items())

get() - accès sécurisé

1species = {"Python": "Python", "Leo": "Lion"}
2
3# get(key) - None si absent
4result = species.get("Python")  # "Python"
5result = species.get("T-Rex")   # None
6
7# get(key, default) - valeur par défaut personnalisée
8result = species.get("T-Rex", "Not found!")  # "Not found!"

setdefault() - renvoyer la valeur OU définir une valeur par défaut

1catalog = {"Python": {"count": 5}}
2
3# Si la clé existe - renvoie la valeur
4python_data = catalog.setdefault("Python", {"count": 0})
5print(python_data)  # {'count': 5}
6
7# Si la clé N'existe PAS - l'ajoute avec la valeur par défaut
8leo_data = catalog.setdefault("Leo", {"count": 0})
9print(leo_data)  # {'count': 0}
10print(catalog)   # {'Python': {...}, 'Leo': {'count': 0}}

update() - mettre à jour/fusionner des dictionnaires

1catalog1 = {"Python": "Python", "Leo": "Lion"}
2catalog2 = {"Elephas": "Elephant", "Giraffa": "Giraffe"}
3new_data = {"Python": "Royal Python"}  # Va écraser
4
5# Mise à jour avec un dictionnaire
6catalog1.update(catalog2)
7print(catalog1)  # {'Python': 'Python', 'Leo': 'Lion', 'Elephas': 'Elephant', 'Giraffa': 'Giraffe'}
8
9# Mise à jour avec des paires clé=valeur
10catalog1.update(discovered_by="Darwin", year=2024)

copy() - copier un dictionnaire

1# ATTENTION - ceci ne copie PAS !
2original = {"A": 1, "B": 2}
3reference = original  # Même référence !
4reference["A"] = 999
5print(original)  # {'A': 999, 'B': 2} - modifié !
6
7# Copie correcte
8original = {"A": 1, "B": 2}
9copy1 = original.copy()  # Copie superficielle
10copy2 = dict(original)   # Alternative
11
12copy1["A"] = 999
13print(original)  # {'A': 1, 'B': 2} - inchangé !
14
15# Copie profonde (pour les dictionnaires imbriqués)
16import copy
17nested = {"team": {"leader": "Darwin", "size": 5}}
18deep = copy.deepcopy(nested)
19deep["team"]["leader"] = "Alex"
20print(nested)  # {'team': {'leader': 'Darwin', 'size': 5}} - inchangé !

Compréhensions de dictionnaire

Comme les compréhensions de liste, tu peux créer des dictionnaires en une seule ligne !

1# Manière traditionnelle
2squares = {}
3for x in range(1, 6):
4    squares[x] = x ** 2
5# {1: 1, 2: 4, 3: 9, 4: 16, 5: 25}
6
7# Compréhension de dictionnaire !
8squares = {x: x ** 2 for x in range(1, 6)}
9# {1: 1, 2: 4, 3: 9, 4: 16, 5: 25}
10
11# Avec une condition
12even_squares = {x: x ** 2 for x in range(1, 11) if x % 2 == 0}
13# {2: 4, 4: 16, 6: 36, 8: 64, 10: 100}
14
15# Échanger les clés et les valeurs
16species = {"Python": "Python", "Leo": "Lion"}
17reversed_dict = {value: key for key, value in species.items()}
18# {"Python": "Python", "Lion": "Leo"}
19
20# À partir de deux listes
21names = ["Python", "Leo", "Elephas"]
22common_names = ["Python", "Lion", "Elephant"]
23catalog = {name: common for name, common in zip(names, common_names)}

Dictionnaires imbriqués

Les dictionnaires peuvent contenir d'autres dictionnaires - parfait pour des données complexes !

1# Catalogue d'expédition avec les détails de chaque espèce
2species_database = {
3    "Python regius": {
4        "common_name": "Royal Python",
5        "characteristics": {
6            "length_m": 1.5,
7            "weight_kg": 2.5,
8            "habitat": "jungle"
9        },
10        "status": "discovered",
11        "discoverer": "Darwin",
12        "date": "2024-01-15"
13    },
14    "Panthera leo": {
15        "common_name": "Lion",
16        "characteristics": {
17            "length_m": 2.5,
18            "weight_kg": 190,
19            "habitat": "savanna"
20        },
21        "status": "observed",
22        "discoverer": "Team B"
23    }
24}
25
26# Accéder aux valeurs imbriquées
27python_length = species_database["Python regius"]["characteristics"]["length_m"]
28print(f"Python length: {python_length}m")
29
30# Accès sécurisé aux valeurs profondément imbriquées
31leo_weight = species_database.get("Panthera leo", {}).get("characteristics", {}).get("weight_kg", "No data")
32print(f"Lion weight: {leo_weight}kg")

Opérations sur les dictionnaires

1# Longueur (nombre de paires clé-valeur)
2species = {"Python": "Python", "Leo": "Lion", "Elephas": "Elephant"}
3count = len(species)  # 3
4
5# Fusion de dictionnaires (Python 3.9+)
6dict1 = {"A": 1, "B": 2}
7dict2 = {"C": 3, "D": 4}
8merged = dict1 | dict2  # {'A': 1, 'B': 2, 'C': 3, 'D': 4}
9
10# Fusion avec écrasement (Python 3.9+)
11dict1 = {"A": 1, "B": 2}
12dict2 = {"B": 999, "C": 3}
13merged = dict1 | dict2  # {'A': 1, 'B': 999, 'C': 3} - B écrasé !
14
15# Opérateur |= (modifie le premier dictionnaire)
16dict1 |= dict2  # dict1 contient maintenant les données fusionnées
17
18# Min/Max des clés
19species = {"Python": 5, "Leo": 12, "Elephas": 3}
20max_key = max(species)  # "Python" (par ordre alphabétique)
21max_value = max(species.values())  # 12
22max_by_value = max(species, key=species.get)  # "Leo" (valeur la plus élevée)

Trier des dictionnaires

1species_count = {
2    "Python": 5,
3    "Leo": 12,
4    "Elephas": 3,
5    "Giraffa": 8
6}
7
8# Trier par clés
9sorted_by_key = dict(sorted(species_count.items()))
10# {'Elephas': 3, 'Giraffa': 8, 'Leo': 12, 'Python': 5}
11
12# Trier par valeurs
13sorted_by_value = dict(sorted(species_count.items(), key=lambda x: x[1]))
14# {'Elephas': 3, 'Python': 5, 'Giraffa': 8, 'Leo': 12}
15
16# Trier par valeurs décroissantes
17sorted_desc = dict(sorted(species_count.items(), key=lambda x: x[1], reverse=True))
18# {'Leo': 12, 'Giraffa': 8, 'Python': 5, 'Elephas': 3}

Exemple pratique - Système de catalogage

1# Système de catalogage des espèces découvertes
2
3species_catalog = {}
4
5def add_species(name, common_name, habitat, dangerous, notes=""):
6    """Ajoute une espèce au catalogue"""
7    species_catalog[name] = {
8        "common_name": common_name,
9        "habitat": habitat,
10        "dangerous": dangerous,
11        "notes": notes,
12        "discovery_date": "2024-11-24"  # Date d'exemple
13    }
14    print(f"Added: {name}")
15
16def show_catalog():
17    """Affiche tout le catalogue"""
18    if not species_catalog:
19        print("Catalog is empty!")
20        return
21
22    print(f"\n=== SPECIES CATALOG ({len(species_catalog)} entries) ===")
23    for name, data in species_catalog.items():
24        danger = "DANGEROUS" if data["dangerous"] else "Safe"
25        print(f"\n{name} ({data['common_name']})")
26        print(f"  Habitat: {data['habitat']}")
27        print(f"  Status: {danger}")
28        if data["notes"]:
29            print(f"  Notes: {data['notes']}")
30
31def search_species(name):
32    """Recherche une espèce par son nom"""
33    if name in species_catalog:
34        data = species_catalog[name]
35        print(f"\nFound: {name}")
36        print(f"Common name: {data['common_name']}")
37        print(f"Habitat: {data['habitat']}")
38        print(f"Dangerous: {'Yes' if data['dangerous'] else 'No'}")
39    else:
40        print(f"\nNot found: {name}")
41
42def filter_by_habitat(habitat):
43    """Filtre les espèces par habitat"""
44    filtered = {name: data for name, data in species_catalog.items()
45                if data["habitat"] == habitat}
46
47    print(f"\nSpecies in habitat '{habitat}': {len(filtered)}")
48    for name in filtered:
49        print(f"  - {name}")
50
51# Utilisation du système
52add_species("Python regius", "Royal Python", "jungle", False, "Calm species")
53add_species("Panthera leo", "Lion", "savanna", True, "Observe from a distance!")
54add_species("Gorilla gorilla", "Gorilla", "jungle", False)
55
56show_catalog()
57search_species("Python regius")
58filter_by_habitat("jungle")

Liste vs Dictionnaire - Lequel utiliser ?

Utilise une liste quand :

  • L'ordre est important
  • Tu as besoin d'un accès par index numérique
  • Tu peux avoir des doublons
  • Collection simple de valeurs

Utilise un dictionnaire quand :

  • Tu as besoin d'un accès rapide par clé
  • Chaque élément a sa propre étiquette unique
  • Les données ont une structure clé-valeur
  • Tu veux vérifier facilement si un élément existe

Exercice pratique

L'éditeur contient le registre d'expédition safari_registry. Complète-le :

  1. Ajoute la clé "vehicle" avec la valeur "jeep"
  2. Change "budget_usd" en 20000
  3. Avec update(), ajoute "species_found": 12 et "photos_taken": 340
  4. Supprime la clé "days_remaining" avec del
Code de cette leçon : main.py
1# Ajouter et mettre à jour les entrées d'un dictionnaire
2
3safari_registry = {
4    "expedition_name": "Serengeti 2024",
5    "leader": "Darwin",
6    "team_size": 5
7}
8
9print("Registre initial :")
10print(safari_registry)
11
12# Ajout d'une nouvelle clé
13safari_registry["location"] = "Tanzania"
14safari_registry["budget_usd"] = 15000
15
16# Mise à jour d'une clé existante
17safari_registry["team_size"] = 7
18
19print("\nAprès modifications :")
20print(safari_registry)
21
22# update() - met à jour plusieurs clés à la fois
23safari_registry.update({
24    "status": "active",
25    "days_remaining": 14,
26    "leader": "Jane"  # Écrase la valeur existante
27})
28
29print("\nAprès update() :")
30print(safari_registry)
31
32# TODO : Ajoute la clé "vehicle" avec la valeur "jeep"
33
34
35# TODO : Change "budget_usd" en 20000
36
37
38# TODO : Utilise update() pour ajouter "species_found": 12 et "photos_taken": 340
39
40
41# TODO : Supprime la clé "days_remaining" avec del
42# del safari_registry["?"]
43
44print("\nRegistre final :")
45for key, value in safari_registry.items():
46    print(f"  {key}: {value}")
47

Résumé

Dans cette leçon, tu as appris :

  • Ce que sont les dictionnaires (paires clé-valeur)
  • Créer et accéder aux dictionnaires
  • Ajouter, modifier, supprimer des éléments
  • Les méthodes : keys(), values(), items(), get(), update(), setdefault()
  • Les compréhensions de dictionnaire
  • Les dictionnaires imbriqués
  • Itérer à travers les dictionnaires
  • Trier et opérations sur les dictionnaires

Point de contrôle

Avant de continuer :

  • Tu comprends la différence entre une liste et un dictionnaire
  • Tu sais utiliser get() au lieu de []
  • Tu connais items(), keys(), values()
  • Tu sais itérer à travers un dictionnaire
  • Tu sais créer des compréhensions de dictionnaire
  • Tu comprends les dictionnaires imbriqués

Dans la prochaine leçon, Darwin te montrera les tuples et les ensembles - des relevés immuables et un registre d'espèces uniques !

Tu as repéré une erreur dans cette leçon ?

Teste tes connaissances

Réponds aux questions de cette leçon. Choisis une réponse pour voir tout de suite si elle est correcte.

  1. 1. Un dictionnaire en Python stocke :

  2. 2. Comment obtenir la valeur de la clé 'name' du dictionnaire « animal » ?

  3. 3. Quel est l'avantage de dict.get('key') par rapport à dict['key'] ?

  4. 4. Que renvoie dict.items() ?

Tâches pratiques dans le jeu

  • Clique dans l'ordre

    Clique les éléments dans le bon ordre :

  • Éditeur de code

    Crée un dictionnaire appelé « tiger » avec les clés : name='Tiger', weight=200, dangerous=True

  • Éditeur de code

    Affiche le nom de l'animal depuis le dictionnaire animal = {'name': 'Python', 'length': 5}

  • Éditeur de code

    Ajoute la clé 'habitat' avec la valeur 'Jungle' au dictionnaire animal = {'name': 'Python', 'length': 5}

  • Tri vertical

    Ordonne les étapes pour construire un catalogue :

  • Tri horizontal

    Ordonne : animal = {'name': 'Tiger'}

  • Clique dans l'ordre

    Clique dans l'ordre : print(animal['name'])

  • Tri vertical

    Ordonne : créer un dictionnaire, ajouter une clé, afficher toutes les clés :

Articles utiles