for x in [1, 2, 3]: print(x, end=" ")
print()
for c in "abc": print(c, end=" ")
print()
for k in {"a": 1, "b": 2}: print(k, end=" ")
print()
for n in range(3): print(n, end=" ")1 2 3
a b c
a b
0 1 2
Vous savez déjà écrire des boucles for et while. Ce chapitre va plus loin : comment itérer proprement sur les structures complexes (dicts, listes imbriquées), et comment enchaîner les opérations de filtrage / agrégation / transformation — les briques de base du traitement de données en Python.
Un objet est itérable si on peut le parcourir avec for. En Python, c’est le cas de :
range.for x in [1, 2, 3]: print(x, end=" ")
print()
for c in "abc": print(c, end=" ")
print()
for k in {"a": 1, "b": 2}: print(k, end=" ")
print()
for n in range(3): print(n, end=" ")1 2 3
a b c
a b
0 1 2
Un objet est itérable s’il a une méthode spéciale __iter__. On peut tester avec hasattr :
print(hasattr([1, 2], "__iter__")) # True
print(hasattr("abc", "__iter__")) # True
print(hasattr(42, "__iter__")) # FalseTrue
True
False
On approfondira le protocole d’itération en Partie 4.
Vu au chapitre 7 de la Partie 1, mais essentielles à maîtriser. Le TOSA teste les trois façons.
personne = {"nom": "Alice", "age": 30, "ville": "Paris"}
for cle in personne: # équivaut à personne.keys()
print(cle)nom
age
ville
for valeur in personne.values():
print(valeur)Alice
30
Paris
La forme la plus utile, à privilégier systématiquement quand vous avez besoin des deux :
for cle, valeur in personne.items():
print(f"{cle} → {valeur}")nom → Alice
age → 30
ville → Paris
| Ce qu’on veut | Méthode |
|---|---|
| Juste les clés | for k in d: |
| Juste les valeurs | for v in d.values(): |
| Les paires clé/valeur | for k, v in d.items(): |
Filtrer = garder certains éléments selon une condition.
notes = [12, 8, 15, 7, 18, 10, 14]
# Ne garder que les notes >= 10
reussites = []
for n in notes:
if n >= 10:
reussites.append(n)
print(reussites)[12, 15, 18, 10, 14]
Agréger = combiner plusieurs valeurs en une seule (somme, moyenne, maximum, comptage…).
notes = [12, 8, 15, 7, 18, 10, 14]
# Somme, moyenne
somme = 0
for n in notes:
somme += n
print("Somme :", somme)
print("Moyenne :", somme / len(notes))Somme : 84
Moyenne : 12.0
# Comptage sous condition
notes = [12, 8, 15, 7, 18, 10, 14]
nb_reussites = 0
for n in notes:
if n >= 10:
nb_reussites += 1
print(f"{nb_reussites} élèves ont la moyenne sur {len(notes)}.")5 élèves ont la moyenne sur 7.
Pour des agrégations simples, Python propose des raccourcis :
notes = [12, 8, 15, 7, 18, 10, 14]
print("Somme :", sum(notes))
print("Moyenne :", sum(notes) / len(notes))
print("Max :", max(notes))
print("Min :", min(notes))Somme : 84
Moyenne : 12.0
Max : 18
Min : 7
Transformer = appliquer une fonction à chaque élément pour produire une nouvelle collection.
notes_sur_20 = [12, 15, 9, 17, 11]
# Convertir en note sur 100
notes_sur_100 = []
for n in notes_sur_20:
notes_sur_100.append(n * 5)
print(notes_sur_100)[60, 75, 45, 85, 55]
# Mettre tous les prénoms en majuscules
prenoms = ["alice", "bob", "charlie"]
majuscules = []
for p in prenoms:
majuscules.append(p.upper())
print(majuscules)['ALICE', 'BOB', 'CHARLIE']
Les 3 opérations (filtrer / agréger / transformer) s’écrivent bien plus élégamment avec les compréhensions de liste — vues au niveau Avancé (Partie 3).
# Filtrer
reussites = [n for n in notes if n >= 10]
# Transformer
notes_sur_100 = [n * 5 for n in notes_sur_20]
# Combiner
reussites_sur_100 = [n * 5 for n in notes if n >= 10]Pour l’instant, le for explicite suffit.
Une boucle dans une autre boucle. Le chapitre 9 de la Partie 1 l’a vu ; rappel pour des usages spécifiques :
matrice = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9],
]
for ligne in matrice:
for valeur in ligne:
print(valeur, end=" ")
print()1 2 3
4 5 6
7 8 9
notes_classe = {
"Alice": [12, 15, 14],
"Bob": [11, 10, 9],
"Charlie": [18, 17, 19],
}
for prenom, notes in notes_classe.items():
moyenne = sum(notes) / len(notes)
print(f"{prenom} : moyenne = {moyenne:.1f}")Alice : moyenne = 13.7
Bob : moyenne = 10.0
Charlie : moyenne = 18.0
Parcourir toutes les combinaisons de deux séquences :
couleurs = ["rouge", "vert", "bleu"]
tailles = ["S", "M", "L"]
for c in couleurs:
for t in tailles:
print(f"{c}-{t}", end=" ")rouge-S rouge-M rouge-L vert-S vert-M vert-L bleu-S bleu-M bleu-L
in et not inDéjà rencontré. Rappels des cas subtils :
# Sur une liste → cherche dans les éléments
print(3 in [1, 2, 3]) # True
# Sur une chaîne → cherche une sous-chaîne
print("ana" in "banane") # True
# Sur un dict → cherche dans les CLÉS
d = {"nom": "Alice", "age": 30}
print("nom" in d) # True
print("Alice" in d) # False ! (valeur, pas clé)
print("Alice" in d.values()) # TrueTrue
True
True
False
True
in n’est pas égal partout
| Structure | Complexité de in |
|---|---|
list / tuple |
O(n) — parcours linéaire |
str |
O(n × m) |
set / frozenset |
O(1) — quasi-instantané |
dict (sur les clés) |
O(1) |
Pour des tests d’appartenance nombreux, convertir en set avant peut accélérer drastiquement.
enumerate() — boucle avec l’indiceRevu en Partie 1. On insiste : c’est LA façon Pythonique d’itérer avec l’indice.
fruits = ["pomme", "banane", "cerise"]
# ❌ Non-Pythonique
for i in range(len(fruits)):
print(i, fruits[i])
print()
# ✅ Pythonique
for i, fruit in enumerate(fruits):
print(i, fruit)
# Avec un démarrage personnalisé
print()
for rang, fruit in enumerate(fruits, start=1):
print(f"{rang}. {fruit}")0 pomme
1 banane
2 cerise
0 pomme
1 banane
2 cerise
1. pomme
2. banane
3. cerise
zip() — parcours parallèlePour parcourir plusieurs séquences en parallèle.
prenoms = ["Alice", "Bob", "Charlie"]
notes = [14, 12, 17]
mentions = ["Bien", "Passable", "Très bien"]
for p, n, m in zip(prenoms, notes, mentions):
print(f"{p} ({n}) : {m}")Alice (14) : Bien
Bob (12) : Passable
Charlie (17) : Très bien
Depuis Python 3.10, on peut ajouter strict=True pour lever une erreur si les longueurs diffèrent :
list(zip([1, 2, 3], ["a", "b"], strict=True))--------------------------------------------------------------------------- ValueError Traceback (most recent call last) Cell In[18], line 1 ----> 1 list(zip([1, 2, 3], ["a", "b"], strict=True)) ValueError: zip() argument 2 is shorter than argument 1
reversed() et sorted()Revus en Partie 1. Rappels dans le contexte d’itération :
# Parcours à l'envers sans modifier
notes = [12, 15, 9, 17]
for n in reversed(notes):
print(n, end=" ")
print()
# Parcours trié sans modifier
for n in sorted(notes):
print(n, end=" ")
print()
# Trié par valeur pour un dict
scores = {"Alice": 14, "Bob": 17, "Charlie": 11}
for nom, score in sorted(scores.items(), key=lambda t: t[1], reverse=True):
print(f"{nom} : {score}")17 9 15 12
9 12 15 17
Bob : 17
Alice : 14
Charlie : 11
range() approfondi| Forme | Génère |
|---|---|
range(n) |
0, 1, ..., n-1 |
range(a, b) |
a, a+1, ..., b-1 |
range(a, b, pas) |
a, a+pas, ..., < b |
print(list(range(5))) # [0, 1, 2, 3, 4]
print(list(range(2, 8))) # [2, 3, 4, 5, 6, 7]
print(list(range(0, 20, 3))) # [0, 3, 6, 9, 12, 15, 18][0, 1, 2, 3, 4]
[2, 3, 4, 5, 6, 7]
[0, 3, 6, 9, 12, 15, 18]
print(list(range(10, 0, -1))) # [10, 9, 8, ..., 1]
print(list(range(10, 0, -2))) # [10, 8, 6, 4, 2][10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
[10, 8, 6, 4, 2]
range est un itérateur paresseux
range(1_000_000_000) ne crée pas un milliard d’entiers en mémoire ! L’objet range calcule les valeurs à la demande pendant l’itération.
import sys
# Un range d'un milliard : 48 octets en mémoire !
gros_range = range(1_000_000_000)
print("Taille d'un gros range :", sys.getsizeof(gros_range), "octets")
# Une liste d'un million : 8 Mo
petite_liste = list(range(1_000_000))
print("Taille d'une liste de 1M :", sys.getsizeof(petite_liste), "octets")Taille d'un gros range : 48 octets
Taille d'une liste de 1M : 8000056 octets
C’est un avantage majeur : vous pouvez boucler sur d’énormes plages sans saturer la mémoire.
Construire un indice :
fruits = ["pomme", "banane", "cerise"]
for i in range(len(fruits)):
print(i, fruits[i]) # Préférez enumerate() en pratique0 pomme
1 banane
2 cerise
Générer une séquence numérique :
carres = []
for i in range(1, 11):
carres.append(i ** 2)
print(carres)[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
Itérer un nombre de fois sans utiliser la variable :
# Convention : _ quand la variable ne sert pas
for _ in range(3):
print("Boum !")Boum !
Boum !
Boum !
Un exemple concret qui combine les trois :
notes = [
("Alice", 14),
("Bob", 8),
("Charlie", 17),
("Diana", 9),
("Eve", 15),
]
# Problème : moyenne des notes des élèves ayant au moins 10
# Filtrer puis agréger
notes_valides = []
for nom, note in notes:
if note >= 10:
notes_valides.append(note)
if notes_valides:
print(f"Moyenne des élèves réussis : {sum(notes_valides) / len(notes_valides):.2f}")
else:
print("Aucun élève n'a la moyenne")Moyenne des élèves réussis : 15.33
Quelle est la forme idiomatique pour parcourir un dict avec clés et valeurs ?
for k in d: print(k, d[k])for k, v in d.items(): print(k, v)for k in d.keys(): print(k, d.get(k))for k, v in d: print(k, v)b) for k, v in d.items(): — la forme idiomatique Python. L’option a) fonctionne mais cherche deux fois la clé dans le dict (moins efficace). L’option d) ne fonctionne pas : parcourir un dict sans méthode donne les clés, pas des paires.
d = {"a": 1, "b": 2}
# Variante inefficace (mais fonctionne)
for k in d:
print(k, d[k])
print()
# Forme idiomatique
for k, v in d.items():
print(k, v)a 1
b 2
a 1
b 2
Que renvoie "Alice" in {"nom": "Alice"} ?
TrueFalseNoneb) False — in teste les clés d’un dict. Ici "Alice" est une valeur. Pour tester une valeur, il faut in d.values().
d = {"nom": "Alice"}
print("Alice" in d)
print("Alice" in d.values())
print("nom" in d)False
True
True
Que renvoie ce code ?
r = range(2, 10, 3)
print(list(r))[2, 5, 8][2, 3, 4, 5, 6, 7, 8, 9][2, 5, 8, 11][3, 6, 9]a) [2, 5, 8] — départ 2, pas 3, arrêt avant 10. Donc 2, 5, 8 (11 serait hors bornes).
print(list(range(2, 10, 3)))[2, 5, 8]
Que fait for _ in range(5): ?
b) Boucle 5 fois sans utiliser la variable — convention Python : _ signale qu’on ignore la variable.
for _ in range(5):
print("Hello", end=" ")Hello Hello Hello Hello Hello
Combien d’itérations effectue cette boucle ?
for i in range(10, 0, -2):
pass45610b) 5 — les valeurs sont 10, 8, 6, 4, 2. La boucle s’arrête avant 0.
print(list(range(10, 0, -2)))
print(len(list(range(10, 0, -2))))[10, 8, 6, 4, 2]
5
Que s’affiche-t-il ?
for i, c in enumerate("abc", start=10):
print(i, c)0 a / 1 b / 2 c10 a / 11 b / 12 ca 10 / b 11 / c 12b) 10 a / 11 b / 12 c — start=10 fait démarrer l’indice à 10.
for i, c in enumerate("abc", start=10):
print(i, c)10 a
11 b
12 c
Quelle structure est la plus rapide pour tester x in ... ?
listtuplestrsetd) set — complexité O(1) (hash table). Les listes et tuples sont en O(n), les chaînes en O(n×m).
# Démonstration (à très grande échelle)
import time
grande_liste = list(range(1_000_000))
grand_set = set(grande_liste)
t0 = time.time()
for _ in range(1000):
_ = 500_000 in grande_liste
print(f"list : {(time.time() - t0)*1000:.1f} ms")
t0 = time.time()
for _ in range(1000):
_ = 500_000 in grand_set
print(f"set : {(time.time() - t0)*1000:.1f} ms")list : 2855.2 ms
set : 0.0 ms
Soit un dictionnaire associant chaque matière à une liste de notes :
notes = {
"Maths": [12, 15, 9, 17],
"Physique": [11, 10, 13, 14],
"Français": [16, 18, 15, 17, 14],
}Affichez la moyenne de chaque matière, arrondie à 1 décimale.
notes = {
"Maths": [12, 15, 9, 17],
"Physique": [11, 10, 13, 14],
"Français": [16, 18, 15, 17, 14],
}
# Pour chaque matière, calculer et afficher la moyennenotes = {
"Maths": [12, 15, 9, 17],
"Physique": [11, 10, 13, 14],
"Français": [16, 18, 15, 17, 14],
}
for matiere, liste_notes in notes.items():
moyenne = sum(liste_notes) / len(liste_notes)
print(f"{matiere:<10} : {moyenne:.1f}")Maths : 13.2
Physique : 12.0
Français : 16.0
À partir d’une liste de tuples (prenom, age), comptez le nombre de majeurs et affichez leurs prénoms.
personnes = [
("Alice", 17),
("Bob", 25),
("Charlie", 15),
("Diana", 30),
("Eve", 19),
]personnes = [
("Alice", 17),
("Bob", 25),
("Charlie", 15),
("Diana", 30),
("Eve", 19),
]
# Compter et afficher les majeurspersonnes = [
("Alice", 17),
("Bob", 25),
("Charlie", 15),
("Diana", 30),
("Eve", 19),
]
majeurs = []
for prenom, age in personnes:
if age >= 18:
majeurs.append(prenom)
print(f"{len(majeurs)} majeur(s) :")
for nom in majeurs:
print(f" - {nom}")3 majeur(s) :
- Bob
- Diana
- Eve
Générez tous les jetons d’un jeu de cartes classique (52 cartes) : produit cartésien des 4 couleurs et des 13 valeurs.
Format attendu : "As de Cœur", "2 de Pique", …, "Roi de Trèfle".
couleurs = ["Cœur", "Carreau", "Pique", "Trèfle"]
valeurs = ["As", "2", "3", "4", "5", "6", "7", "8", "9", "10", "Valet", "Dame", "Roi"]
# Générer toutes les combinaisons
cartes = []
...
print(f"Total : {len(cartes)} cartes")
print("Premières :", cartes[:3])
print("Dernières :", cartes[-3:])couleurs = ["Cœur", "Carreau", "Pique", "Trèfle"]
valeurs = ["As", "2", "3", "4", "5", "6", "7", "8", "9", "10", "Valet", "Dame", "Roi"]
cartes = []
for couleur in couleurs:
for valeur in valeurs:
cartes.append(f"{valeur} de {couleur}")
print(f"Total : {len(cartes)} cartes")
print("Premières :", cartes[:3])
print("Dernières :", cartes[-3:])Total : 52 cartes
Premières : ['As de Cœur', '2 de Cœur', '3 de Cœur']
Dernières : ['Valet de Trèfle', 'Dame de Trèfle', 'Roi de Trèfle']
Soit trois listes parallèles représentant les données de capteurs :
timestamps = ["09:00", "10:00", "11:00", "12:00"]
temperatures = [12.5, 14.0, 16.3, 18.1]
humidites = [65, 62, 58, 55]Produisez un affichage synthétique aligné, avec une ligne par mesure.
timestamps = ["09:00", "10:00", "11:00", "12:00"]
temperatures = [12.5, 14.0, 16.3, 18.1]
humidites = [65, 62, 58, 55]
# Afficher un tableau alignétimestamps = ["09:00", "10:00", "11:00", "12:00"]
temperatures = [12.5, 14.0, 16.3, 18.1]
humidites = [65, 62, 58, 55]
print(f"{'Heure':<8}{'Temp. (°C)':>12}{'Humidité (%)':>14}")
print("-" * 34)
for h, t, hum in zip(timestamps, temperatures, humidites):
print(f"{h:<8}{t:>12.1f}{hum:>14}")Heure Temp. (°C) Humidité (%)
----------------------------------
09:00 12.5 65
10:00 14.0 62
11:00 16.3 58
12:00 18.1 55
for k in d, for v in d.values(), for k, v in d.items().in sur un set est en O(1). Sur une list, O(n). Énorme différence sur de gros volumes.enumerate au lieu de range(len(...)). zip pour plusieurs séquences en parallèle.range est paresseux : consomme peu de mémoire même sur des milliards d’éléments._ comme nom de variable signale qu’on ignore sa valeur.← Chapitre précédent : Les f-strings • Chapitre suivant : Références et mutabilité →