Essayer de coder ← Retour aux sujets

for, while et parcours

répéter

Une boucle répète un bloc d'instructions. for parcourt une séquence ou un range, while répète tant qu'une condition reste vraie.

for i in range(5):
i prend les valeurs 0, 1, 2, 3, 4
for x in liste:
Parcourt les valeurs d'une liste, d'un texte, d'un tuple…
for i, x in enumerate(liste):
L'indice et la valeur à chaque tour
for cle, val in d.items():
Parcourt un dictionnaire
while n > 0:
Répète tant que la condition est vraie
break / continue
Quitter la boucle / passer au tour suivant
parcours.py
for i, lettre in enumerate(["a", "b"]):
    print(i, lettre)
Affichage
0 a
1 b
✓ Habitude propre

Préfère for dès que tu parcours une séquence ; réserve while aux cas où le nombre de tours n'est pas connu d'avance.

Schémas à connaître

accumuler

Quelques constructions reviennent dans presque tous les programmes : accumuler, compter, chercher, construire une liste.

somme += x
Accumuler : somme, produit, compteur
if x > maxi: maxi = x
Chercher un maximum ou un minimum
resultat.append(x)
Construire une liste au fil de la boucle
n //= 10
Retirer le dernier chiffre d'un nombre
for … else
Le else s'exécute si aucun break n'a eu lieu
[x * x for x in liste]
Compréhension : une boucle en une ligne
somme.py
somme = 0
for i in range(1, 101):
    somme += i
print(somme)
Affichage
5050

🔄 Le cours : répéter des instructions

Une boucle répète un bloc d'instructions. Python en propose deux : for, quand on parcourt des éléments connus (une liste, un texte, une suite d'entiers), et while, quand on répète tant qu'une condition est vraie sans savoir à l'avance combien de tours il faudra. Dans les deux cas, le bloc répété est indenté sous la ligne d'en-tête qui se termine par :.

La boucle for avec range

range fabrique une suite d'entiers : range(n) va de 0 à n - 1, range(a, b) de a à b - 1, et range(a, b, pas) avance de pas en pas (négatif pour compter à l'envers). La borne de fin est toujours exclue. On voit le contenu avec list(...).

range.py
print(list(range(5)))
print(list(range(2, 7)))
print(list(range(0, 20, 5)))
print(list(range(5, 0, -1)))
for i in range(3):
    print("tour", i)
Affichage
[0, 1, 2, 3, 4]
[2, 3, 4, 5, 6]
[0, 5, 10, 15]
[5, 4, 3, 2, 1]
tour 0
tour 1
tour 2

Parcourir directement les éléments

Un for peut parcourir n'importe quelle séquence : liste, tuple, texte (lettre par lettre), dictionnaire (ses clés). Pour avoir clés et valeurs, on utilise .items(). Parcourir les éléments eux-mêmes évite de manipuler des indices, donc les erreurs d'un cran.

parcours_elements.py
notes = [12, 15, 9]
total = 0
for note in notes:
    total += note
print(total)

for lettre in "NSI":
    print(lettre)

scores = {"Ada": 18, "Lin": 17}
for nom, note in scores.items():
    print(nom, "->", note)
Affichage
36
N
S
I
Ada -> 18
Lin -> 17

enumerate et zip

enumerate(liste) donne des couples (indice, valeur) : parfait quand on a besoin de la position, avec start=1 pour numéroter à partir de 1. zip(a, b) parcourt deux séquences en parallèle (il s'arrête à la plus courte).

enumerate_zip.py
langages = ["Python", "C", "Java"]
for i, nom in enumerate(langages):
    print(i, nom)
for i, nom in enumerate(langages, start=1):
    print(f"{i}. {nom}")

prenoms = ["Ada", "Lin"]
notes = [18, 17]
for p, n in zip(prenoms, notes):
    print(p, n)
Affichage
0 Python
1 C
2 Java
1. Python
2. C
3. Java
Ada 18
Lin 17

La boucle while

while condition: teste la condition avant chaque tour et s'arrête dès qu'elle devient fausse. Il faut donc que le corps de la boucle fasse évoluer quelque chose pour qu'elle finisse un jour. Ici, on additionne les chiffres de 2845 : n % 10 est le dernier chiffre, n //= 10 le retire.

chiffres.py
n = 2845
somme = 0
while n > 0:
    somme += n % 10
    n //= 10
print(somme)
Affichage
19

while convient quand on ne connaît pas le nombre de tours : combien d'années faut-il pour doubler un capital placé à 5 % ?

capital.py
capital = 1000
annees = 0
while capital < 2000:
    capital *= 1.05
    annees += 1
print(annees, round(capital, 2))
Affichage
15 2078.93

break, continue et else

break quitte immédiatement la boucle, continue abandonne le tour en cours et passe au suivant. Une clause else placée après une boucle s'exécute seulement si la boucle s'est terminée sans break : pratique pour dire « rien trouvé ».

break_continue.py
for n in range(10):
    if n == 7:
        break
    if n % 2 == 0:
        continue
    print(n)
Affichage
1
3
5
premier.py
for n in [29, 21]:
    for d in range(2, n):
        if n % d == 0:
            print(n, "= produit de", d, "et", n // d)
            break
    else:
        print(n, "est premier")
Affichage
29 est premier
21 = produit de 3 et 7

Autre usage classique de while True : répéter jusqu'à obtenir une réponse valable, puis sortir avec break. Ici, on simule les réponses d'un utilisateur avec une liste.

saisie_valide.py
reponses = ["abc", "", "42"]
i = 0
while True:
    saisie = reponses[i]
    i += 1
    if saisie.isdigit():
        break
print("saisie valide :", saisie)
Affichage
saisie valide : 42

Boucles imbriquées

Une boucle peut contenir une autre boucle : pour chaque tour de la boucle extérieure, la boucle intérieure recommence depuis le début. Le nombre de tours se multiplie : n lignes de p cases, c'est n × p tours (voir notations T(n) et O()). print(*ligne) affiche les éléments d'une liste séparés par des espaces.

table.py
for i in range(1, 4):
    ligne = []
    for j in range(1, 4):
        ligne.append(i * j)
    print(*ligne)
Affichage
1 2 3
2 4 6
3 6 9
paires.py
n = 5
paires = 0
for i in range(n):
    for j in range(i + 1, n):
        paires += 1
print(paires)
Affichage
10

Ici, la boucle intérieure part de i + 1 : on compte les paires (i, j) avec i < j, soit n(n - 1) / 2 paires, un coût en O(n²).

Schémas classiques : accumuler, compter, chercher

SchémaInitialisationDans la boucle
Sommesomme = 0somme += x
Compteurnb = 0if condition: nb += 1
Maximummaxi = valeurs[0]if x > maxi: maxi = x
Recherchetrouve = Noneif condition and trouve is None: trouve = x
Liste résultatresultat = []resultat.append(f(x))
schemas.py
valeurs = [4, 8, 15, 16, 23, 42]
somme = 0
nb_pairs = 0
maxi = valeurs[0]
premier_multiple_de_5 = None
for v in valeurs:
    somme += v
    if v % 2 == 0:
        nb_pairs += 1
    if v > maxi:
        maxi = v
    if premier_multiple_de_5 is None and v % 5 == 0:
        premier_multiple_de_5 = v
print(somme, nb_pairs, maxi, premier_multiple_de_5)
Affichage
108 4 42 15

Compréhensions : construire une liste en une ligne

Une compréhension de liste a la forme [expression for x in sequence if condition] (la partie if est facultative). C'est une boucle for qui construit une liste. Le même principe existe pour les ensembles ({...}), les dictionnaires ({cle: valeur for ...}) et, entre parenthèses, pour des générateurs qui ne fabriquent pas la liste (utiles dans sum, max, any…).

comprehensions.py
carres = [x * x for x in range(6)]
pairs = [x for x in range(10) if x % 2 == 0]
majuscules = [m.upper() for m in ["nsi", "python"]]
couples = [(i, j) for i in range(2) for j in range(2)]
print(carres)
print(pairs)
print(majuscules)
print(couples)
Affichage
[0, 1, 4, 9, 16, 25]
[0, 2, 4, 6, 8]
['NSI', 'PYTHON']
[(0, 0), (0, 1), (1, 0), (1, 1)]
comprehensions_2.py
mots = ["chat", "chien", "oiseau"]
longueurs = {m: len(m) for m in mots}
initiales = {m[0] for m in mots}
total = sum(len(m) for m in mots)
print(longueurs)
print(sorted(initiales))
print(total)
Affichage
{'chat': 4, 'chien': 5, 'oiseau': 6}
['c', 'o']
15

Combien de tours ?

Pour juger le coût d'une boucle, on compte ses tours : une boucle simple sur n éléments fait n tours (O(n)), deux boucles imbriquées en font n × n (O(n²)), et une boucle qui divise la variable par 2 à chaque tour s'arrête en environ log₂(n) tours.

moitie.py
n = 1000
etapes = 0
while n > 1:
    n //= 2
    etapes += 1
print(etapes)
Affichage
9

⚠️ Erreurs fréquentes

L'erreur d'un cran

Parcourir les indices d'une liste de n éléments, c'est range(n) (de 0 à n - 1). Écrire range(len(t) + 1) fait un tour de trop : le dernier indice n'existe pas.

À éviter
faux.py
t = [10, 20, 30]
for i in range(len(t) + 1):
    print(t[i])
Erreur
IndexError: list index out of range
Correct
correct.py
t = [10, 20, 30]
for i in range(len(t)):
    print(t[i])
Affichage
10
20
30

range s'arrête avant la borne

range(1, 10) contient 1, 2, …, 9 mais pas 10. Pour additionner les entiers de 1 à 100, on écrit range(1, 101).

bornes.py
print(list(range(1, 10)))
print(sum(range(1, 100)), sum(range(1, 101)))
Affichage
[1, 2, 3, 4, 5, 6, 7, 8, 9]
4950 5050

La boucle infinie

Si la condition d'un while ne devient jamais fausse, le programme ne s'arrête plus (dans un terminal : Ctrl + C). Vérifie toujours qu'une variable testée évolue dans le corps de la boucle.

À éviter
faux.py
n = 5
while n > 0:
    print(n)
Correct
correct.py
n = 5
while n > 0:
    print(n)
    n -= 1
Affichage
5
4
3
2
1

Modifier une liste pendant qu'on la parcourt

Supprimer des éléments d'une liste pendant qu'on la parcourt décale les indices : certains éléments sont sautés, sans aucune erreur. Construis plutôt une nouvelle liste.

À éviter
faux.py
nombres = [2, 4, 5, 6]
for x in nombres:
    if x % 2 == 0:
        nombres.remove(x)
print(nombres)
Affichage
[4, 5]
Correct
correct.py
nombres = [2, 4, 5, 6]
nombres = [x for x in nombres if x % 2 != 0]
print(nombres)
Affichage
[5]

Confondre l'élément et son indice

Dans for x in liste, x est la valeur, pas la position. L'utiliser comme indice provoque une TypeError (ou, avec des entiers, un résultat faux).

À éviter
faux.py
lettres = ["a", "b"]
for l in lettres:
    print(lettres[l])
Erreur
TypeError: list indices must be integers or slices, not str
Correct
correct.py
lettres = ["a", "b"]
for i, l in enumerate(lettres):
    print(i, l)
Affichage
0 a
1 b

break ne sort que de la boucle la plus interne

Dans deux boucles imbriquées, break n'arrête que la boucle qui le contient : la boucle extérieure continue. Pour sortir des deux, on met la double boucle dans une fonction et on utilise return.

break_interne.py
for i in range(3):
    for j in range(3):
        if j == 1:
            break
        print(i, j)
Affichage
0 0
1 0
2 0

Un accumulateur oublié

total += x suppose que total existe déjà : il faut l'initialiser avant la boucle (à 0 pour une somme, à [] pour une liste).

À éviter
faux.py
for x in [1, 2, 3]:
    total += x
print(total)
Erreur
NameError: name 'total' is not defined
Correct
correct.py
total = 0
for x in [1, 2, 3]:
    total += x
print(total)
Affichage
6

La variable de boucle reste accessible

Contrairement à d'autres langages, la variable d'une boucle for existe encore après la boucle (avec sa dernière valeur). Pratique parfois, source de confusion souvent : ne la réutilise pas par mégarde.

variable_survivante.py
for i in range(3):
    pass
print(i)
Affichage
2

📋 Aide-mémoire

BesoinBoucle
Répéter n foisfor _ in range(n):
Parcourir les valeursfor x in liste:
Indice et valeurfor i, x in enumerate(liste):
Deux listes en parallèlefor a, b in zip(liste1, liste2):
Clés et valeurs d'un dictionnairefor cle, val in d.items():
Compter à reboursfor i in range(n, 0, -1):
Répéter jusqu'à une conditionwhile condition: (et faire évoluer la condition)
  • range(a, b, pas) : de a inclus à b exclu ; list(range(...)) pour voir les valeurs.
  • break quitte la boucle ; continue passe au tour suivant ; else après la boucle s'exécute si aucun break n'a eu lieu.
  • Boucles imbriquées : les tours se multiplient (n × p) ; une boucle qui divise par 2 fait environ log₂(n) tours.
  • Compréhension : [expression for x in sequence if condition] ; ensemble {...}, dictionnaire {cle: val for ...}, générateur (...).
  • Ne modifie pas une liste pendant que tu la parcours : construis-en une nouvelle.
  • Initialise les accumulateurs avant la boucle (somme = 0, resultat = []).