Introduction
Tu as une liste de 200 utilisateurs et tu veux afficher le nom de chacun. Tu fais quoi ? Tu écris 200 lignes de print() ? Évidemment non. C'est exactement pour ça que la boucle for en Python existe : elle te permet de répéter une action sur chaque élément d'une séquence, sans dupliquer une seule ligne de code.
La boucle for est probablement la structure que tu utiliseras le plus en Python. Parcourir une liste, lire un fichier ligne par ligne, générer des données, filtrer des résultats — tout passe par elle. Et contrairement à d'autres langages, Python a une syntaxe particulièrement élégante pour ça.
Ce guide te montre tout ce qu'il faut savoir : de la syntaxe de base jusqu'aux list comprehensions, en passant par range(), enumerate(), zip(), et les erreurs classiques qui piègent tous les débutants. Chaque concept est illustré par du code que tu peux copier et exécuter directement.
La boucle for en Python : syntaxe de base
En Python, la boucle for ne fonctionne pas comme en C ou en Java. Tu ne déclares pas de compteur, tu ne gères pas de condition d'arrêt. Tu itères directement sur les éléments d'un itérable (liste, chaîne, tuple, dictionnaire, etc.).
Voici la syntaxe :
for element in iterable:
# instructions à répéter
Un premier exemple concret — afficher chaque fruit d'une liste :
fruits = ["pomme", "banane", "cerise", "mangue"]
for fruit in fruits:
print(fruit)
Résultat :
pomme
banane
cerise
mangue
Quelques points importants :
- La variable
fruitprend successivement la valeur de chaque élément de la liste. - Le bloc indenté après les deux-points (
:) constitue le corps de la boucle. - L'indentation est obligatoire — c'est Python qui délimite les blocs comme ça, pas avec des accolades.
- Le nom de la variable d'itération est libre :
fruit,x,item, peu importe. Choisis un nom qui a du sens.
Un deuxième exemple — calculer la somme d'une liste de nombres :
notes = [15, 12, 18, 9, 14]
total = 0
for note in notes:
total += note
moyenne = total / len(notes)
print(f"Moyenne : {moyenne}") # Moyenne : 13.6
Tu vois le principe : la boucle for traite chaque élément un par un, dans l'ordre. Pas besoin d'index, pas besoin de compteur. C'est ce qui rend Python si lisible.
Itérer sur différents types
La boucle for ne se limite pas aux listes. Elle fonctionne sur tout objet itérable en Python. Voyons les cas les plus courants.
Sur une chaîne de caractères (string)
Chaque caractère est traité individuellement :
mot = "Python"
for lettre in mot:
print(lettre, end=" ")
# P y t h o n
C'est pratique pour compter des voyelles, vérifier la présence d'un caractère, ou construire un chiffrement lettre par lettre.
Sur un tuple
Même logique qu'une liste :
coordonnees = (48.8566, 2.3522)
for valeur in coordonnees:
print(valeur)
Sur un dictionnaire
C'est là que ça devient intéressant. Par défaut, itérer sur un dictionnaire parcourt les clés :
utilisateur = {"nom": "Alice", "age": 28, "ville": "Lyon"}
for cle in utilisateur:
print(cle)
# nom
# age
# ville
Pour accéder aux valeurs, utilise .values() :
for valeur in utilisateur.values():
print(valeur)
# Alice
# 28
# Lyon
Et pour récupérer clé et valeur en même temps, utilise .items() — c'est la forme la plus courante :
for cle, valeur in utilisateur.items():
print(f"{cle} : {valeur}")
# nom : Alice
# age : 28
# ville : Lyon
Note le déballage de tuple (tuple unpacking) : .items() renvoie des paires (clé, valeur), et Python les assigne automatiquement aux deux variables.
Sur un ensemble (set)
langages = {"Python", "JavaScript", "Rust"}
for langage in langages:
print(langage)
Attention : un set n'a pas d'ordre garanti. L'ordre d'affichage peut varier d'une exécution à l'autre.
La fonction range() en détail
Quand tu as besoin d'un compteur numérique — répéter une action 10 fois, générer des indices, compter de 2 en 2 — c'est range() qu'il te faut. Consulte la documentation officielle de range() pour les détails techniques.
range() accepte 1, 2 ou 3 arguments :
Un seul argument : range(n)
Génère les nombres de 0 à n-1 :
for i in range(5):
print(i)
# 0, 1, 2, 3, 4
Pourquoi range(5) s'arrête à 4 et pas à 5 ? Parce que Python utilise des intervalles semi-ouverts : la borne de fin est toujours exclue. C'est cohérent avec l'indexation qui commence à 0 — range(5) produit exactement 5 éléments.
Deux arguments : range(debut, fin)
for i in range(3, 8):
print(i)
# 3, 4, 5, 6, 7
Là encore, la borne 8 est exclue.
Trois arguments : range(debut, fin, pas)
Le troisième argument contrôle le pas (l'incrément) :
# Compter de 2 en 2
for i in range(0, 11, 2):
print(i)
# 0, 2, 4, 6, 8, 10
# Compte à rebours
for i in range(10, 0, -1):
print(i)
# 10, 9, 8, 7, 6, 5, 4, 3, 2, 1
Un cas d'usage classique — afficher une table de multiplication :
n = 7
for i in range(1, 11):
print(f"{n} x {i} = {n * i}")
range() ne crée pas une liste en mémoire. C'est un objet paresseux (lazy) : il génère chaque nombre à la demande. Tu peux écrire range(1_000_000_000) sans faire exploser ta RAM.
enumerate() : obtenir l'index et la valeur
Problème classique : tu veux parcourir une liste et connaître l'index de chaque élément. Le réflexe de débutant, c'est de faire ça :
# ❌ Mauvaise habitude
prenoms = ["Alice", "Bob", "Charlie"]
for i in range(len(prenoms)):
print(f"{i} : {prenoms[i]}")
Ça marche, mais c'est moche et non-pythonique. La bonne approche, c'est enumerate() :
# ✅ Pythonique
prenoms = ["Alice", "Bob", "Charlie"]
for i, prenom in enumerate(prenoms):
print(f"{i} : {prenom}")
# 0 : Alice
# 1 : Bob
# 2 : Charlie
enumerate() renvoie des paires (index, valeur) que tu déballes directement dans la boucle. C'est plus lisible, plus sûr (pas de risque d'erreur d'indice), et plus rapide.
Commencer à un autre index
Par défaut, l'index commence à 0. Mais tu peux le changer avec le paramètre start :
questions = ["Quel est ton nom ?", "Quel âge as-tu ?", "Où habites-tu ?"]
for num, question in enumerate(questions, start=1):
print(f"Question {num} : {question}")
# Question 1 : Quel est ton nom ?
# Question 2 : Quel âge as-tu ?
# Question 3 : Où habites-tu ?
C'est parfait pour numéroter des éléments à partir de 1 dans un affichage utilisateur.
Cas d'usage réel : trouver la position d'un élément
scores = [45, 89, 72, 95, 60, 88]
for i, score in enumerate(scores):
if score >= 90:
print(f"Excellent score ({score}) trouvé à la position {i}")
# Excellent score (95) trouvé à la position 3
zip() : parcourir plusieurs listes
Tu as deux listes liées — des noms et des notes par exemple — et tu veux les parcourir en parallèle. C'est le rôle de zip() :
noms = ["Alice", "Bob", "Charlie"]
notes = [15, 12, 18]
for nom, note in zip(noms, notes):
print(f"{nom} a eu {note}/20")
# Alice a eu 15/20
# Bob a eu 12/20
# Charlie a eu 18/20
zip() combine les éléments de même position en tuples. Tu peux zipper plus de deux listes :
noms = ["Alice", "Bob", "Charlie"]
notes = [15, 12, 18]
villes = ["Paris", "Lyon", "Marseille"]
for nom, note, ville in zip(noms, notes, villes):
print(f"{nom} ({ville}) : {note}/20")
Attention aux listes de tailles différentes
Par défaut, zip() s'arrête à la plus courte des listes :
a = [1, 2, 3, 4, 5]
b = ["x", "y", "z"]
for num, lettre in zip(a, b):
print(num, lettre)
# 1 x
# 2 y
# 3 z
# (4 et 5 sont ignorés)
Si tu veux aller jusqu'à la plus longue, utilise itertools.zip_longest :
from itertools import zip_longest
a = [1, 2, 3, 4, 5]
b = ["x", "y", "z"]
for num, lettre in zip_longest(a, b, fillvalue="-"):
print(num, lettre)
# 1 x
# 2 y
# 3 z
# 4 -
# 5 -
Combiner zip() et enumerate()
Tu peux les chaîner pour avoir l'index en bonus :
matieres = ["Maths", "Physique", "Info"]
notes = [16, 13, 19]
for i, (matiere, note) in enumerate(matieres_notes := zip(matieres, notes), start=1):
print(f"{i}. {matiere} : {note}/20")
Ou, plus lisiblement :
for i, (matiere, note) in enumerate(zip(matieres, notes), start=1):
print(f"{i}. {matiere} : {note}/20")
# 1. Maths : 16/20
# 2. Physique : 13/20
# 3. Info : 19/20
Contrôler la boucle : break, continue et else
Parfois, tu ne veux pas parcourir toute la séquence. Python te donne trois mots-clés pour contrôler le flux d'une boucle for.
break : sortir immédiatement
break interrompt la boucle dès qu'il est atteint :
nombres = [3, 7, 2, 9, 1, 5, 8]
for n in nombres:
if n == 9:
print("Trouvé !")
break
print(f"Test de {n}...")
# Test de 3...
# Test de 7...
# Test de 2...
# Trouvé !
Utilise break quand tu cherches un élément précis et que tu veux arrêter dès que tu l'as trouvé. C'est plus performant que de continuer à parcourir inutilement.
continue : passer à l'itération suivante
continue saute le reste du bloc et passe directement à l'élément suivant :
nombres = [1, -3, 4, -7, 2, 8, -1]
for n in nombres:
if n < 0:
continue
print(n)
# 1
# 4
# 2
# 8
Ici, on ignore tous les nombres négatifs. C'est utile pour filtrer sans imbriquer plein de if.
else sur une boucle for
Peu de développeurs connaissent cette syntaxe. Le bloc else d'un for s'exécute uniquement si la boucle se termine sans break :
def est_premier(n):
if n < 2:
return False
for i in range(2, int(n**0.5) + 1):
if n % i == 0:
return False # diviseur trouvé, pas premier
else:
return True # aucun diviseur trouvé
print(est_premier(17)) # True
print(est_premier(15)) # False
Un autre exemple — chercher un utilisateur :
utilisateurs = ["alice", "bob", "charlie"]
cherche = "david"
for user in utilisateurs:
if user == cherche:
print(f"{cherche} trouvé !")
break
else:
print(f"{cherche} n'existe pas dans la liste.")
# david n'existe pas dans la liste.
Le else après for évite d'utiliser un booléen trouve = False pour gérer ce cas. C'est élégant, mais utilise-le avec parcimonie — beaucoup de développeurs ne connaissent pas cette syntaxe et risquent de mal lire ton code.
Les boucles imbriquées
Une boucle imbriquée, c'est une boucle for à l'intérieur d'une autre. Pour chaque itération de la boucle externe, la boucle interne s'exécute entièrement.
Parcourir une matrice (liste de listes)
matrice = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]
for ligne in matrice:
for valeur in ligne:
print(valeur, end=" ")
print() # retour à la ligne
# 1 2 3
# 4 5 6
# 7 8 9
Dessiner un triangle
hauteur = 5
for i in range(1, hauteur + 1):
for j in range(i):
print("*", end="")
print()
# *
# **
# ***
# ****
# *****
Trouver des paires
nombres = [2, 4, 7, 3, 8]
cible = 10
for i in range(len(nombres)):
for j in range(i + 1, len(nombres)):
if nombres[i] + nombres[j] == cible:
print(f"{nombres[i]} + {nombres[j]} = {cible}")
# 2 + 8 = 10
# 7 + 3 = 10
Attention : les boucles imbriquées ont une complexité qui grandit vite. Deux boucles sur une liste de n éléments, c'est n² opérations. Sur 1000 éléments, ça fait 1 million d'opérations. Utilise-les quand c'est nécessaire, mais cherche toujours s'il existe une approche plus efficace (dictionnaires, ensembles, etc.).
Boucle for vs list comprehension
Les list comprehensions (ou listes en compréhension) sont une syntaxe compacte pour créer des listes à partir d'une boucle. C'est l'un des outils les plus puissants de Python.
Syntaxe de base
Au lieu d'écrire :
# Boucle for classique
carres = []
for n in range(1, 6):
carres.append(n ** 2)
# [1, 4, 9, 16, 25]
Tu peux écrire :
# List comprehension
carres = [n ** 2 for n in range(1, 6)]
# [1, 4, 9, 16, 25]
Même résultat, une seule ligne, et c'est plus rapide à l'exécution (Python optimise les comprehensions en interne).
Avec une condition (filtre)
# Garder seulement les nombres pairs
nombres = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
pairs = [n for n in nombres if n % 2 == 0]
# [2, 4, 6, 8, 10]
Avec transformation et condition
# Mettre en majuscules les prénoms de plus de 3 lettres
prenoms = ["al", "alice", "bob", "charlie", "ed"]
resultat = [p.upper() for p in prenoms if len(p) > 3]
# ['ALICE', 'CHARLIE']
Quand utiliser quoi ?
Utilise une list comprehension quand :
- Tu construis une nouvelle liste à partir d'une transformation simple.
- La logique tient sur une ligne lisible.
- Il n'y a pas d'effets de bord (pas de
print(), pas de modification d'état externe).
Utilise une boucle for classique quand :
- La logique est complexe (plusieurs conditions,
break,continue). - Tu as des effets de bord (écriture fichier, appels API, affichage).
- La lisibilité en souffre si tu compresses tout sur une ligne.
# ❌ Trop complexe pour une comprehension
resultat = [transformer(x) for x in donnees if valider(x) and x.actif and x.score > seuil]
# ✅ Plus lisible en boucle classique
resultat = []
for x in donnees:
if not valider(x):
continue
if not x.actif:
continue
if x.score <= seuil:
continue
resultat.append(transformer(x))
La règle d'or : si ta comprehension dépasse ~80 caractères ou nécessite une réflexion pour être comprise, repasse en boucle classique.
5 erreurs de débutants à éviter
Ces erreurs, tout le monde les fait au début. Les connaître te fera gagner des heures de débogage.
1. Modifier une liste pendant qu'on itère dessus
# ❌ Bug : comportement imprévisible
nombres = [1, 2, 3, 4, 5]
for n in nombres:
if n % 2 == 0:
nombres.remove(n)
print(nombres) # [1, 3, 5] ? Non ! → [1, 3, 5] parfois, [1, 3, 4] d'autres fois
Quand tu supprimes un élément, les indices se décalent et Python saute des éléments. La solution : créer une nouvelle liste.
# ✅ Correct : list comprehension
nombres = [1, 2, 3, 4, 5]
nombres = [n for n in nombres if n % 2 != 0]
print(nombres) # [1, 3, 5]
2. Utiliser range(len()) quand c'est inutile
# ❌ Non-pythonique
fruits = ["pomme", "banane", "cerise"]
for i in range(len(fruits)):
print(fruits[i])
# ✅ Pythonique
for fruit in fruits:
print(fruit)
# ✅ Si tu as besoin de l'index
for i, fruit in enumerate(fruits):
print(i, fruit)
range(len(...)) est un signal d'alerte. Dans 90% des cas, tu peux l'éviter avec une itération directe ou enumerate().
3. Oublier les deux-points
# ❌ SyntaxError
for i in range(5)
print(i)
# ✅ Correct
for i in range(5):
print(i)
Les deux-points (:) à la fin de la ligne for sont obligatoires. L'oubli arrive souvent quand tu viens d'un langage qui utilise des accolades.
4. Croire que la variable de boucle est une copie
# La variable de boucle est une référence, pas une copie
listes = [[1, 2], [3, 4], [5, 6]]
for sous_liste in listes:
sous_liste.append(0) # modifie la liste originale !
print(listes) # [[1, 2, 0], [3, 4, 0], [5, 6, 0]]
Avec des entiers ou des chaînes (types immuables), pas de souci. Mais avec des listes, des dictionnaires ou des objets (types mutables), la variable de boucle pointe vers l'objet original. Si tu le modifies, l'original change aussi.
5. Oublier que range() exclut la borne supérieure
# ❌ Erreur fréquente : vouloir afficher 1 à 10
for i in range(10):
print(i) # affiche 0 à 9, pas 1 à 10
# ✅ Correct
for i in range(1, 11):
print(i) # affiche 1 à 10
Retiens : range(a, b) produit les nombres de a inclus à b exclu. Si tu veux inclure b, écris range(a, b + 1).
Tableau récapitulatif
Voici un aide-mémoire des formes les plus courantes de la boucle for en Python. Garde-le sous la main, il couvre la grande majorité des cas que tu rencontreras. Pour la référence complète, consulte la documentation officielle Python sur les boucles for.
| Forme | Code | Usage |
|---|---|---|
| Itération simple | for x in liste: | Parcourir une séquence |
| Avec index | for i, x in enumerate(liste): | Accéder à l'index et la valeur |
| Compteur | for i in range(n): | Répéter n fois |
| Plage personnalisée | for i in range(a, b, pas): | Séquence numérique sur mesure |
| Deux listes | for x, y in zip(l1, l2): | Parcourir en parallèle |
| Dictionnaire | for k, v in d.items(): | Clés et valeurs |
| Comprehension | [f(x) for x in liste] | Créer une liste transformée |
| Comprehension filtrée | [x for x in liste if cond] | Créer une liste filtrée |
| Avec break | for x in liste: ... break | Sortir dès qu'on trouve |
| Avec continue | for x in liste: ... continue | Sauter certains éléments |
| Avec else | for x in liste: ... else: | Exécuter si pas de break |
Pour aller plus loin
Tu connais maintenant la boucle for en Python sous toutes ses formes : syntaxe de base, range(), enumerate(), zip(), break/continue, boucles imbriquées, et list comprehensions. Tu sais aussi quelles erreurs éviter pour ne pas perdre de temps à déboguer.
La prochaine étape logique après les boucles, c'est de structurer ton code avec des fonctions. Consulte notre guide complet sur les fonctions en Python pour apprendre à créer des fonctions réutilisables, gérer les paramètres et maîtriser la portée des variables.
Mais lire du code et en écrire, ce sont deux choses très différentes. La boucle for ne s'assimile vraiment qu'en pratiquant — en résolvant des problèmes concrets, pas en relisant des exemples.
Si tu veux passer de la théorie à la pratique, essaie un atelier Python sur GoGoKodo. Tu écris du vrai code dans le navigateur, tu obtiens un feedback instantané, et tu progresses étape par étape sur des exercices construits pour consolider chaque concept.
Quelques ressources complémentaires pour approfondir :
- La documentation officielle Python sur les boucles for — la référence absolue.
- Real Python — un excellent tutoriel anglophone avec des exemples avancés.
- Nos ateliers interactifs Python — pour pratiquer directement dans le navigateur, avec correction automatique.
La prochaine fois que tu te retrouves à copier-coller du code pour traiter chaque élément un par un, souviens-toi : il y a une boucle for pour ça.