dict : clé et valeur

Objectifs de la leçon
  • Créer un dict et lire une valeur par sa clé
  • Ajouter, mettre à jour et supprimer des paires clé-valeur
  • Utiliser get avec une valeur par défaut pour éviter une KeyError
  • Parcourir un dictionnaire avec keys, values et items, et travailler avec une liste de dictionnaires

Qu’allons-nous apprendre ?

Un dict (Dictionary, dictionnaire) est une structure qui contient des paires clé-valeur. Au lieu d’accéder par position ([0]), on accède par nom (["name"]).

Pourquoi en avons-nous besoin ?

Dans le tuple ("Dana", 24, "Haifa"), il faut se souvenir que la position 1 est l’âge. Avec 15 champs, c’est la recette des bugs. Un dict résout ce problème :

student = {"name": "Dana", "age": 24, "city": "Haifa"}
student["age"]   # clear and readable

dict est peut-être la structure la plus importante pour les semaines à venir :

  • JSON (demain) : le format dans lequel on enregistre des fichiers et on envoie des informations sur le réseau. En Python, il devient un dict.
  • Les thèmes backend et bases de données : chaque requête et chaque réponse d’une API est essentiellement un dict. {"id": 7, "name": "Dana"}.
  • Tout « enregistrement », comme un utilisateur, un produit ou une commande, se représente facilement par un dict.

Explication à partir des bases

Qu’est-ce qu’un dict ?

  • Chaque élément est une paire : une clé (Key) → une valeur (Value).
  • Des clés uniques — il n’y a pas deux clés identiques. Affecter à une clé existante remplace la valeur.
  • Modifiable.
  • Conserve l’ordre d’insertion (depuis Python 3.7).
  • Une clé est généralement un str ou un int. Une valeur peut être n’importe quoi : un nombre, du texte, une liste, et même un autre dict.
Analogie : un dictionnaire / un annuaire

Dans un vrai dictionnaire, on cherche un mot (la clé) et on obtient une définition (la valeur). On ne cherche pas « la définition à la position 5 000 du livre ». Dans un annuaire : nom → numéro. Deux personnes ne peuvent pas apparaître avec exactement le même nom en tant qu’entrées séparées. Une nouvelle entrée avec le même nom remplace la précédente.

Syntaxe

# create
empty = {}
student = {"name": "Dana", "age": 24}

# read
student["name"]                 # "Dana" - KeyError if the key does not exist
student.get("email")            # None - no error if missing
student.get("email", "N/A")     # "N/A" - default value if missing

# add / update (same syntax!)
student["email"] = "dana@mail.com"   # new key -> added
student["age"] = 25                  # existing key -> updated

# delete
del student["email"]            # delete a key (KeyError if missing)
age = student.pop("age")        # delete and return the value

# check
"name" in student               # True - checks KEYS, not values
len(student)                    # number of key-value pairs

# iterate
for key in student:             # keys
for value in student.values():  # values
for key, value in student.items():   # pairs (tuples!)

Premier exemple de code

week-2/student_dict.py :

student = {"name": "Dana", "age": 24, "city": "Haifa"}

print("Name:", student["name"])
print("Age:", student["age"])

student["age"] = 25
student["email"] = "dana@mail.com"
print("Updated:", student)

del student["city"]
print("After delete:", student)

print("Has email?", "email" in student)
print("Phone:", student.get("phone", "not provided"))

Sortie :

Name: Dana
Age: 24
Updated: {'name': 'Dana', 'age': 25, 'city': 'Haifa', 'email': 'dana@mail.com'}
After delete: {'name': 'Dana', 'age': 25, 'email': 'dana@mail.com'}
Has email? True
Phone: not provided

Analyse du code ligne par ligne

LigneExplication
{"name": "Dana", ...}Une clé, deux-points, une valeur. Les paires sont séparées par des virgules.
student["name"]Lecture par clé : la valeur "Dana".
student["age"] = 25La clé existe, donc la valeur est mise à jour.
student["email"] = "..."La clé n’existe pas, donc elle est ajoutée (à la fin). Exactement la même syntaxe !
del student["city"]Suppression de toute la paire.
"email" in studentVérifie si la clé existe.
student.get("phone", "not provided")La clé n’existe pas, donc la valeur par défaut est renvoyée, sans erreur.

Un autre exemple

Une liste de dictionnaires — la structure la plus courante pour des données « réelles » (un tableau : chaque dict est une ligne). Et aussi le comptage avec un dict. week-2/products.py :

products = [
    {"id": 1, "name": "Laptop", "price": 3500, "category": "electronics"},
    {"id": 2, "name": "Mouse", "price": 80, "category": "electronics"},
    {"id": 3, "name": "Desk", "price": 900, "category": "furniture"},
    {"id": 4, "name": "Chair", "price": 450, "category": "furniture"},
]

print("--- Catalog ---")
for product in products:
    print(product["id"], product["name"], product["price"], "NIS")

expensive = []
for product in products:
    if product["price"] > 500:
        expensive.append(product["name"])
print("Over 500 NIS:", expensive)

count_by_category = {}
for product in products:
    category = product["category"]
    count_by_category[category] = count_by_category.get(category, 0) + 1
print("Count by category:", count_by_category)

for category, count in count_by_category.items():
    print(category, "->", count, "products")

Sortie :

--- Catalog ---
1 Laptop 3500 NIS
2 Mouse 80 NIS
3 Desk 900 NIS
4 Chair 450 NIS
Over 500 NIS: ['Laptop', 'Desk']
Count by category: {'electronics': 2, 'furniture': 2}
electronics -> 2 products
furniture -> 2 products

Analyse :

  • products est une liste dont chaque élément est un dict. product["price"] = le prix du produit courant dans la boucle.
  • Le modèle de comptage : count_by_category.get(category, 0) + 1. Si la catégorie n’est pas encore dans le dictionnaire, get renvoie 0, puis 0+1 = 1. Si elle y est déjà, on obtient le compte existant et on ajoute 1. C’est un modèle qui revient sans cesse.
  • .items() — renvoie des paires (key, value) sous forme de tuples, et for category, count in les décompose (l’Unpacking de la leçon précédente).

Un dict dans un dict

Une valeur peut elle-même être un dict :

user = {
    "name": "Dana",
    "address": {"city": "Haifa", "street": "Herzl 10"},
    "hobbies": ["chess", "running"],
}
print(user["address"]["city"])   # Haifa
print(user["hobbies"][0])        # chess

On y accède « couche par couche » : user["address"] renvoie un dict, et sur lui ["city"]. C’est exactement la structure du JSON.

Erreur courante

Erreur 1 : une KeyError sur une clé qui n’existe pas.

student = {"name": "Dana"}
print(student["age"])
KeyError: 'age'

La correction : student.get("age") (renvoie None), student.get("age", 0) (une valeur par défaut), ou vérifier d’abord avec if "age" in student:.

Erreur 2 : chercher une valeur avec in.

student = {"name": "Dana"}
print("Dana" in student)
False

in sur un dict vérifie les clés. Pour vérifier les valeurs : "Dana" in student.values().

Erreur 3 : une faute de frappe dans une clé, qui crée une nouvelle clé au lieu de mettre à jour.

student = {"name": "Dana", "age": 24}
student["Age"] = 25
print(student)
{'name': 'Dana', 'age': 24, 'Age': 25}

Aucune erreur ! Une nouvelle clé "Age" a simplement été ajoutée, et "age" est restée à 24. Les clés sont sensibles à la casse. C’est une Logical Error silencieuse, alors gardez des noms de clés cohérents (snake_case).

Erreur 4 : une liste comme clé.

locations = {[32, 35]: "Haifa"}
TypeError: unhashable type: 'list'

Une clé doit être Immutable. Si vous avez besoin d’une clé composée de plusieurs valeurs, utilisez un tuple : {(32, 35): "Haifa"}. (Nous expliquerons le lien avec Immutable dans la leçon suivante.)

Exercices

Les exercices n’utilisent que ce qui a été vu dans cette leçon et les précédentes. Essayez d’abord seul, et n’ouvrez la solution qu’ensuite.

Exercice 1: Une fiche d’étudiant

Créez un dictionnaire student avec le nom "Dana", l’âge 24 et la ville "Haifa". Ensuite :

  1. Mettez à jour l’âge à 25.
  2. Ajoutez un e-mail "dana@mail.com".
  3. Supprimez la ville.
  4. Affichez le dictionnaire, et le téléphone avec get et la valeur par défaut "none".

Résultat attendu :

{'name': 'Dana', 'age': 25, 'email': 'dana@mail.com'}
none
Afficher la solution
student = {"name": "Dana", "age": 24, "city": "Haifa"}

student["age"] = 25
student["email"] = "dana@mail.com"
del student["city"]

print(student)
print(student.get("phone", "none"))
{'name': 'Dana', 'age': 25, 'email': 'dana@mail.com'}
none

student["phone"] lancerait une KeyError. get renvoie une valeur par défaut quand la clé n’existe pas.

Exercice 2: Compter les mots

Écrivez une fonction count_words(text) qui renvoie un dictionnaire : chaque mot (en minuscules) → combien de fois il apparaît.

counts = count_words("the cat and the dog and THE bird")
print(counts)

Résultat attendu :

{'the': 3, 'cat': 1, 'and': 2, 'dog': 1, 'bird': 1}
Afficher la solution
def count_words(text):
    counts = {}
    for word in text.lower().split():
        counts[word] = counts.get(word, 0) + 1
    return counts


counts = count_words("the cat and the dog and THE bird")
print(counts)
{'the': 3, 'cat': 1, 'and': 2, 'dog': 1, 'bird': 1}

counts.get(word, 0) renvoie 0 pour un mot pas encore compté — ainsi, pas besoin d’un if séparé pour un nouveau mot.

Exercice 3: Une liste de dictionnaires

products = [
    {"name": "Laptop", "price": 3500, "category": "electronics"},
    {"name": "Mouse", "price": 80, "category": "electronics"},
    {"name": "Desk", "price": 900, "category": "furniture"},
]
  1. Affichez les noms des produits dont le prix est inférieur à 1000.
  2. Construisez un dictionnaire qui compte combien de produits il y a dans chaque catégorie, et affichez-le.

Résultat attendu :

Mouse
Desk
{'electronics': 2, 'furniture': 1}
Afficher la solution
products = [
    {"name": "Laptop", "price": 3500, "category": "electronics"},
    {"name": "Mouse", "price": 80, "category": "electronics"},
    {"name": "Desk", "price": 900, "category": "furniture"},
]

for product in products:
    if product["price"] < 1000:
        print(product["name"])

counts = {}
for product in products:
    category = product["category"]
    counts[category] = counts.get(category, 0) + 1
print(counts)
Mouse
Desk
{'electronics': 2, 'furniture': 1}

Exercice 4: Parcourir un dictionnaire

stock = {"apple": 12, "banana": 0, "cherry": 5}

Parcourez le dictionnaire avec items() et affichez chaque article et sa quantité. Pour un article dont la quantité vaut 0, affichez out of stock.

Résultat attendu :

apple -> 12
banana -> out of stock
cherry -> 5
Afficher la solution
stock = {"apple": 12, "banana": 0, "cherry": 5}

for name, quantity in stock.items():
    if quantity == 0:
        print(name, "->", "out of stock")
    else:
        print(name, "->", quantity)
apple -> 12
banana -> out of stock
cherry -> 5

items() renvoie des paires clé-valeur, et l’Unpacking dans la boucle découpe chaque paire en deux variables.

Exercice 5: Un dictionnaire imbriqué

user = {
    "name": "Dana",
    "address": {"city": "Haifa", "street": "Herzl"},
    "hobbies": ["chess", "running"],
}

Affichez la ville, le premier loisir, et ajoutez un loisir "music". À la fin, affichez la liste des loisirs.

Résultat attendu :

Haifa
chess
['chess', 'running', 'music']
Afficher la solution
user = {
    "name": "Dana",
    "address": {"city": "Haifa", "street": "Herzl"},
    "hobbies": ["chess", "running"],
}

print(user["address"]["city"])
print(user["hobbies"][0])
user["hobbies"].append("music")
print(user["hobbies"])
Haifa
chess
['chess', 'running', 'music']

Chaque [ ] descend d’un niveau : user["address"] est un dictionnaire, et ["city"] en extrait une valeur. C’est exactement la structure du JSON.

Résumé

  • dict {key: value} — accès par clé et non par position. Les clés sont uniques.
  • d[key] = value — ajoute si elle est nouvelle, met à jour si elle existe.
  • d[key] lance une KeyError sur une clé manquante. d.get(key, default) ne lance rien.
  • in vérifie les clés. Parcourir : keys(), values(), items() (paires).
  • Une liste de dictionnaires = un tableau. Un dict dans un dict = du JSON.
  • Le modèle de comptage : counts[x] = counts.get(x, 0) + 1.

Documentation officielle