Boucle for en Python : Guide Complet avec Exemples

15 min de lecture Python

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 :

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 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 :

Utilise une boucle for classique quand :

# ❌ 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.

FormeCodeUsage
Itération simplefor x in liste:Parcourir une séquence
Avec indexfor i, x in enumerate(liste):Accéder à l'index et la valeur
Compteurfor i in range(n):Répéter n fois
Plage personnaliséefor i in range(a, b, pas):Séquence numérique sur mesure
Deux listesfor x, y in zip(l1, l2):Parcourir en parallèle
Dictionnairefor 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 breakfor x in liste: ... breakSortir dès qu'on trouve
Avec continuefor x in liste: ... continueSauter certains éléments
Avec elsefor 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 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.