Aller au contenu principal

Tuples et Dictionnaires

Les tuples et les dictionnaires sont deux structures de données fondamentales en Python. Les tuples permettent de stocker des collections ordonnées et immuables, tandis que les dictionnaires associent des clés à des valeurs.


1. Les Tuples

Créer un tuple

Un tuple se crée avec des parenthèses ou avec la fonction tuple().

# Tuple littéral
coordonnees = (48.8566, 2.3522)
couleurs_rgb = (255, 128, 0)
jours = ("lundi", "mardi", "mercredi")

# Depuis une liste
nombres = tuple([1, 2, 3, 4, 5])

# Tuple vide
vide = ()

# Tuple avec un seul élément — la virgule est OBLIGATOIRE !
singleton = (42,)
print(type(singleton)) # <class 'tuple'>

# Sans virgule, ce n'est pas un tuple
pas_un_tuple = (42)
print(type(pas_un_tuple)) # <class 'int'>
La virgule est essentielle

Pour créer un tuple d'un seul élément, la virgule finale est obligatoire : (42,) et non (42).

Accéder aux éléments

Les tuples sont ordonnés : on accède aux éléments par leur index (commence à 0).

fruits = ("pomme", "banane", "cerise", "datte")

print(fruits[0]) # pomme
print(fruits[-1]) # datte (dernier élément)
print(fruits[1:3]) # ('banane', 'cerise') — slicing

# Longueur
print(len(fruits)) # 4

Tuples immuables

Un tuple ne peut pas être modifié après sa création. Toute tentative de modification lève une erreur.

point = (10, 20)
# point[0] = 15 # TypeError: 'tuple' object does not support item assignment

Déballage (unpacking)

Le déballage permet d'assigner chaque élément d'un tuple à une variable distincte.

coordonnees = (48.8566, 2.3522)
latitude, longitude = coordonnees
print(f"Latitude: {latitude}, Longitude: {longitude}")

# Déballage étendu avec *
premier, *milieu, dernier = (1, 2, 3, 4, 5)
print(premier) # 1
print(milieu) # [2, 3, 4]
print(dernier) # 5

# Échange de variables en une ligne
a, b = 10, 20
a, b = b, a
print(a, b) # 20 10

Méthodes des tuples

Les tuples disposent de deux méthodes principales :

notes = (15, 18, 12, 18, 10, 15)

print(notes.count(18)) # 2 — nombre d'occurrences de 18
print(notes.index(12)) # 2 — index de la première occurrence de 12

Quand utiliser un tuple plutôt qu'une liste ?

SituationUtiliser
Données fixes (coordonnées GPS, couleur RGB)Tuple
Retour multiple d'une fonctionTuple
Clé d'un dictionnaireTuple
Collection à modifierListe
Ordre de traitement variableListe
# Bon usage des tuples
COULEURS = {
"rouge": (255, 0, 0),
"vert": (0, 255, 0),
"bleu": (0, 0, 255),
}

# Ligne d'une base de données (id, nom, age)
ligne_db = (1, "Alice", 30)
id_user, nom, age = ligne_db

Named tuples (mention rapide)

Le module collections fournit namedtuple pour créer des tuples dont les champs ont un nom.

from collections import namedtuple

Point = namedtuple('Point', ['x', 'y'])
p = Point(10, 20)
print(p.x) # 10
print(p.y) # 20
print(p) # Point(x=10, y=20)

Exercice 1 — Créer un tuple et le déballer

Bonne pratique - Déballage de tuple

Le déballage de tuple rend le code plus lisible que l'accès par index. Privilégiez nom, age = personne plutôt que nom = personne[0]; age = personne[1].


2. Les Dictionnaires

Un dictionnaire (dict) est une collection de paires clé : valeur. Les clés sont uniques et les valeurs peuvent être de n'importe quel type.

Créer un dictionnaire

# Dictionnaire litteral
etudiant = {
"nom": "Bob",
"age": 22,
"notes": [14, 16, 18],
}

# Avec dict()
config = dict(host="localhost", port=5432, debug=True)

# Dictionnaire vide
vide = {}
vide2 = dict()

Accéder aux valeurs

etudiant = {"nom": "Alice", "age": 30, "ville": "Lyon"}

# Accès direct — lève KeyError si la clé est absente
print(etudiant["nom"]) # Alice

# Accès sécurisé avec .get() — renvoie None (ou une valeur par défaut) si absent
print(etudiant.get("age")) # 30
print(etudiant.get("email")) # None
print(etudiant.get("email", "N/A")) # N/A

Ajouter et modifier

profil = {"nom": "Charlie", "age": 25}

# Ajouter une nouvelle clé
profil["email"] = "charlie@example.com"

# Modifier une valeur existante
profil["age"] = 26

print(profil)
# {'nom': 'Charlie', 'age': 26, 'email': 'charlie@example.com'}

Supprimer des entrées

inventaire = {"pommes": 10, "bananes": 5, "cerises": 20}

# del — lève KeyError si absent
del inventaire["bananes"]

# .pop() — renvoie la valeur supprimée, KeyError si absent sans défaut
nb_cerises = inventaire.pop("cerises")
print(nb_cerises) # 20

# .pop() avec valeur par défaut — sans KeyError
val = inventaire.pop("mangues", 0)
print(val) # 0

# Vider tout le dictionnaire
inventaire.clear()
print(inventaire) # {}

Méthodes principales

capitale = {"France": "Paris", "Italie": "Rome", "Espagne": "Madrid"}

# Clés, valeurs, paires
print(list(capitale.keys())) # ['France', 'Italie', 'Espagne']
print(list(capitale.values())) # ['Paris', 'Rome', 'Madrid']
print(list(capitale.items())) # [('France', 'Paris'), ...]

# Fusionner avec update()
capitale.update({"Allemagne": "Berlin", "France": "PARIS"})

# Copie superficielle
copie = capitale.copy()

Tester la présence d'une clé

config = {"debug": True, "version": "1.0"}

if "debug" in config:
print("Mode debug actif")

if "timeout" not in config:
print("Pas de timeout configuré")

Itérer sur un dictionnaire

notes = {"maths": 16, "physique": 14, "info": 18}

# Itérer sur les clés (défaut)
for matiere in notes:
print(matiere)

# Itérer sur les clés et valeurs
for matiere, note in notes.items():
print(f"{matiere}: {note}/20")

# Itérer sur les valeurs uniquement
for note in notes.values():
print(note)

Exercice 2 — Accès sécurisé avec .get()

Bonne pratique - Accès sécurisé

Préférez toujours d.get("cle", valeur_defaut) à d["cle"] quand vous n'êtes pas certain que la clé existe. Cela évite les KeyError inattendues.


Exercice 3 — Itérer sur les paires clé/valeur

Bonne pratique - Itération sur les dictionnaires

Utilisez toujours .items() quand vous avez besoin des clés ET des valeurs. C'est plus lisible et plus efficace que d'accéder à d[k] dans une boucle sur les clés.


Compréhensions de dictionnaire

Comme les listes en compréhension, les dictionnaires supportent une syntaxe compacte pour les construire.

# Doubler les valeurs
prix = {"pomme": 1.2, "banane": 0.8, "cerise": 3.5}
prix_doubles = {fruit: p * 2 for fruit, p in prix.items()}
print(prix_doubles)

# Filtrer — garder seulement les fruits à moins de 2 euros
prix_abordables = {f: p for f, p in prix.items() if p < 2}
print(prix_abordables)

# Inverser cles et valeurs
capitales = {"France": "Paris", "Italie": "Rome"}
inverse = {v: k for k, v in capitales.items()}
print(inverse) # {'Paris': 'France', 'Rome': 'Italie'}

# Construire depuis deux listes
noms = ["a", "b", "c"]
vals = [1, 2, 3]
d = {k: v for k, v in zip(noms, vals)}
print(d) # {'a': 1, 'b': 2, 'c': 3}

Exercice 4 — Compréhension de dictionnaire

Bonne pratique - Compréhensions

Les compréhensions de dictionnaire sont puissantes mais ne pas abuser : si la logique est complexe, une boucle for classique est plus lisible.


Dictionnaires imbriqués

Un dictionnaire peut contenir d'autres dictionnaires comme valeurs.

etudiants = {
"alice": {
"age": 22,
"notes": {"maths": 16, "info": 18},
"ville": "Paris",
},
"bob": {
"age": 24,
"notes": {"maths": 12, "info": 15},
"ville": "Lyon",
},
}

# Acces imbriquE
print(etudiants["alice"]["notes"]["info"]) # 18

# Acces securise en cascade
note_physique = etudiants.get("alice", {}).get("notes", {}).get("physique", "N/A")
print(note_physique) # N/A

Exercice 5 — Accès dans un dictionnaire imbriqué

Bonne pratique - Dictionnaires imbriqués

Pour les structures très imbriquées, envisagez d'utiliser des classes ou des dataclasses Python qui rendent l'accès aux attributs plus explicite et les erreurs plus claires.


Exercice 6 — Mettre à jour un dictionnaire

Bonne pratique - update()

La méthode .update() permet de fusionner plusieurs clés en une seule opération. Elle est plus lisible que plusieurs affectations individuelles quand on met à jour plusieurs clés à la fois.


Dictionnaires et JSON

Les dictionnaires Python et le format JSON sont très proches. Le module json permet de convertir l'un en l'autre.

import json

# Dict Python -> chaine JSON
profil = {"nom": "Alice", "age": 30, "actif": True}
json_str = json.dumps(profil, indent=2, ensure_ascii=False)
print(json_str)
# {
# "nom": "Alice",
# "age": 30,
# "actif": true
# }

# Chaine JSON -> Dict Python
data = json.loads('{"nom": "Bob", "score": 42}')
print(data["nom"]) # Bob
print(type(data)) # <class 'dict'>

Quiz de révision


Quelle syntaxe crée un tuple à un seul élément ?


Que retourne d.get('cle_absente', 'defaut') si la clé n'existe pas ?


Quelle méthode permet d'itérer sur les clés ET les valeurs d'un dictionnaire ?


Un tuple peut-il être utilisé comme clé de dictionnaire ?


Quelle est la différence entre del d['cle'] et d.pop('cle') ?


📌 Une solution