17  Les boucles for et while

Les boucles permettent de répéter un bloc d’instructions — soit un nombre défini de fois, soit tant qu’une condition est vraie. C’est l’un des piliers absolus de la programmation. Python propose deux boucles : for et while.

17.1 Pourquoi des boucles ?

Imaginez que vous voulez afficher les nombres de 1 à 10. Sans boucle :

print(1)
print(2)
print(3)
# ... 7 lignes de plus
print(10)

Imaginez maintenant jusqu’à 1000. Impraticable. Les boucles résolvent ce problème :

for i in range(1, 11):
    print(i, end=" ")
1 2 3 4 5 6 7 8 9 10 

17.2 La boucle for

En Python, for ne compte pas comme dans d’autres langages. Il parcourt chaque élément d’une collection.

for <variable> in <collection>:
    <instructions>

Parcourir une liste

fruits = ["pomme", "banane", "cerise"]

for fruit in fruits:
    print(fruit)
pomme
banane
cerise

Parcourir une chaîne

Une chaîne est une séquence de caractères, donc itérable :

for lettre in "Python":
    print(lettre)
P
y
t
h
o
n

Parcourir un dictionnaire

personne = {"nom": "Alice", "age": 30, "ville": "Paris"}

# Par défaut : les clés
for cle in personne:
    print(cle)
nom
age
ville
# Par paires (idiomatique)
for cle, valeur in personne.items():
    print(cle, "→", valeur)
nom → Alice
age → 30
ville → Paris

Parcourir un set

couleurs = {"rouge", "vert", "bleu"}
for c in couleurs:
    print(c)
bleu
rouge
vert

Attention : l’ordre n’est pas garanti pour un set !

17.3 La fonction range()

Pour boucler sur des nombres, on utilise range() qui génère une séquence d’entiers.

Forme Génère
range(n) 0, 1, 2, ..., n-1
range(debut, fin) debut, debut+1, ..., fin-1
range(debut, fin, pas) avec un pas personnalisé
# range(5) : de 0 à 4
for i in range(5):
    print(i, end=" ")
0 1 2 3 4 
# range(1, 6) : de 1 à 5
for i in range(1, 6):
    print(i, end=" ")
1 2 3 4 5 
# range(0, 20, 2) : de 0 à 19 par pas de 2
for i in range(0, 20, 2):
    print(i, end=" ")
0 2 4 6 8 10 12 14 16 18 
# Pas négatif : décompte
for i in range(10, 0, -1):
    print(i, end=" ")
10 9 8 7 6 5 4 3 2 1 
⚠️ Piège TOSA : range(1, 10) va jusqu’à 9, pas 10

La borne de fin est exclue, comme pour le slicing. Pour aller jusqu’à 10, il faut range(1, 11).

print(list(range(1, 10)))        # [1, 2, 3, 4, 5, 6, 7, 8, 9]
print(list(range(1, 11)))        # [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
[1, 2, 3, 4, 5, 6, 7, 8, 9]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

Exemples d’usage

Calculer une somme :

somme = 0
for i in range(1, 101):
    somme += i
print("Somme de 1 à 100 :", somme)
Somme de 1 à 100 : 5050

Afficher une table de multiplication :

n = 7
for i in range(1, 11):
    print(f"{n} × {i} = {n * i}")
7 × 1 = 7
7 × 2 = 14
7 × 3 = 21
7 × 4 = 28
7 × 5 = 35
7 × 6 = 42
7 × 7 = 49
7 × 8 = 56
7 × 9 = 63
7 × 10 = 70

Parcourir une liste avec son indice :

fruits = ["pomme", "banane", "cerise"]
for i in range(len(fruits)):
    print(i, ":", fruits[i])
0 : pomme
1 : banane
2 : cerise
Plus idiomatique : enumerate

Parcourir une liste avec son indice se fait mieux avec enumerate() (vu au chapitre 10) :

fruits = ["pomme", "banane", "cerise"]
for i, fruit in enumerate(fruits):
    print(i, ":", fruit)
0 : pomme
1 : banane
2 : cerise

Plus lisible, plus Pythonique. À privilégier.

17.4 La boucle while

Là où for parcourt une collection, while répète tant qu’une condition est vraie.

while <condition>:
    <instructions>

Exemple simple — compter de 1 à 5 :

i = 1
while i <= 5:
    print(i, end=" ")
    i += 1
1 2 3 4 5 

Anatomie :

  1. On initialise i = 1.
  2. On teste la condition i <= 5.
  3. Si vraie, on exécute le bloc.
  4. On modifie i pour progresser (sinon → boucle infinie !).
  5. On retourne à l’étape 2.
⚠️ Danger : la boucle infinie

Si la condition ne devient jamais fausse, la boucle tourne sans fin et bloque votre programme.

# ❌ Boucle infinie : i ne change jamais !
i = 0
while i < 10:
    print(i)
    # oubli de i += 1

# Pour arrêter : Ctrl+C dans le terminal

Règle d’or : dans un while, quelque chose dans le bloc doit faire évoluer la condition vers False.

Cas typique : saisie utilisateur jusqu’à validation

reponse = ""
while reponse not in ("oui", "non"):
    reponse = input("Oui ou non ? ").lower().strip()

print("Vous avez répondu :", reponse)

for vs while : quand choisir ?

Utiliser for quand… Utiliser while quand…
On connaît la collection à parcourir On ne sait pas à l’avance combien d’itérations
On répète un nombre fixe de fois (range) On boucle tant qu’une condition est vraie
Parcours d’une liste, chaîne, dict, set Saisie utilisateur, attente d’un événement

En Python, on utilise for dans ~90 % des cas. while est réservé aux cas où for ne suffit pas.

17.5 Les instructions break et continue

Ces deux instructions permettent de contrôler finement l’exécution d’une boucle.

break — sortir de la boucle

break interrompt immédiatement la boucle, même si la condition est encore vraie.

# Chercher un élément et sortir dès qu'on le trouve
liste = [3, 7, 12, 25, 8, 14]
cible = 25

for n in liste:
    if n == cible:
        print("Trouvé !")
        break
    print("Ce n'est pas", n)
Ce n'est pas 3
Ce n'est pas 7
Ce n'est pas 12
Trouvé !

continue — passer à l’itération suivante

continue saute le reste du bloc et passe directement à l’itération suivante.

# Afficher uniquement les nombres pairs
for n in range(1, 11):
    if n % 2 != 0:
        continue      # on saute les impairs
    print(n, end=" ")
2 4 6 8 10 
break/continue : à utiliser avec parcimonie

break et continue sont utiles mais rendent le code moins linéaire. Si vous vous surprenez à en abuser, c’est souvent le signe qu’il faut restructurer la boucle.

Pour filtrer des éléments, on préfère souvent en Partie 3 les compréhensions :

# Au lieu de :
pairs = []
for n in range(1, 11):
    if n % 2 != 0:
        continue
    pairs.append(n)

# On écrira :
pairs = [n for n in range(1, 11) if n % 2 == 0]

C’est plus concis et plus lisible.

17.6 Boucles imbriquées

On peut mettre une boucle à l’intérieur d’une autre. Utile pour parcourir des structures à deux dimensions.

for i in range(1, 4):
    for j in range(1, 4):
        print(f"{i}×{j}={i*j}", end="  ")
    print()          # retour à la ligne après chaque ligne
1×1=1  1×2=2  1×3=3  
2×1=2  2×2=4  2×3=6  
3×1=3  3×2=6  3×3=9  

Affichage d’un carré d’étoiles

taille = 5
for ligne in range(taille):
    for col in range(taille):
        print("*", end=" ")
    print()
* * * * * 
* * * * * 
* * * * * 
* * * * * 
* * * * * 
⚠️ Attention à la complexité

Deux boucles imbriquées sur n éléments → n × n = n² itérations. Pour une liste de 10 000 éléments, ça fait 100 millions d’itérations. Acceptable sur de petites données, catastrophique sur de grosses.

Ce point sera approfondi au niveau Avancé (complexité algorithmique).

17.7 for ... range vs boucle sur une collection

Il existe deux écoles pour parcourir une liste. L’école « Python » est largement préférable.

fruits = ["pomme", "banane", "cerise"]

# ❌ Style non-Pythonique (mais fonctionnel)
for i in range(len(fruits)):
    print(i, fruits[i])
0 pomme
1 banane
2 cerise
# ✅ Style Pythonique
for i, fruit in enumerate(fruits):
    print(i, fruit)
0 pomme
1 banane
2 cerise
# ✅ Style Pythonique (si on n'a pas besoin de l'indice)
for fruit in fruits:
    print(fruit)
pomme
banane
cerise

Le TOSA teste les deux styles — sachez reconnaître le second (plus moderne).

17.8 La clause else de boucle (bonus utile)

Python a une particularité : on peut mettre un else à la fin d’une boucle. Il s’exécute si la boucle se termine normalement (sans break).

# Chercher un nombre premier dans une plage
for n in range(2, 10):
    if n == 7:
        print("Trouvé 7 !")
        break
else:
    print("Pas trouvé")          # ne s'exécute pas ici car on a break

# Version où on ne trouve pas
for n in range(2, 10):
    if n == 99:
        break
else:
    print("99 non trouvé dans la plage")    # s'exécute
Trouvé 7 !
99 non trouvé dans la plage

Peu utilisé en pratique, mais à connaître pour le TOSA.


🧩 Quiz 3.1 — Les boucles

Question 1

Combien de fois s’exécute print("Hello") ?

for i in range(5):
    print("Hello")
  1. 4
  2. 5
  3. 6
  4. 0

b) 5range(5) génère 0, 1, 2, 3, 4, soit 5 valeurs.

compteur = 0
for i in range(5):
    compteur += 1
print("Itérations :", compteur)
Itérations : 5

Question 2

Que vaut i après la boucle ?

for i in range(3):
    pass
  1. 0
  2. 2
  3. 3
  4. i n’existe plus

b) 2 — après la boucle, i conserve la dernière valeur prise. range(3) finit à 2.

for i in range(3):
    pass
print(i)
2

Nota : contrairement à d’autres langages, la variable de boucle persiste après celle-ci.

Question 3

Que s’affiche-t-il ?

for i in range(2, 10, 3):
    print(i, end=" ")
  1. 2 3 4 5 6 7 8 9
  2. 2 5 8
  3. 2 4 6 8
  4. 3 6 9

b) 2 5 8 — on commence à 2, avec un pas de 3, on s’arrête avant 10. Soit 2, 5, 8.

for i in range(2, 10, 3):
    print(i, end=" ")
2 5 8 

Question 4

Que s’affiche-t-il ?

for i in range(5):
    if i == 2:
        break
    print(i)
  1. 0 1 2
  2. 0 1
  3. 0 1 3 4
  4. 2 3 4

b) 0 1break arrête la boucle dès i == 2, avant le print. Les valeurs 2, 3, 4 ne sont pas traitées.

for i in range(5):
    if i == 2:
        break
    print(i)
0
1

Question 5

Que s’affiche-t-il ?

for i in range(5):
    if i == 2:
        continue
    print(i)
  1. 0 1 2
  2. 0 1 3 4
  3. 0 1
  4. 3 4

b) 0 1 3 4continue saute l’itération courante mais continue avec les suivantes.

for i in range(5):
    if i == 2:
        continue
    print(i)
0
1
3
4

Question 6

Combien d’itérations fait cette boucle ?

i = 0
while i < 5:
    i += 2
  1. 2
  2. 3
  3. 5
  4. Infini

b) 3i prend successivement les valeurs 0, 2, 4 avant d’atteindre 6 (sortie). Soit 3 itérations.

i = 0
compteur = 0
while i < 5:
    compteur += 1
    i += 2
print("Itérations :", compteur)
Itérations : 3

Question 7

Que s’affiche-t-il ?

for lettre in "abc":
    for chiffre in "12":
        print(lettre + chiffre, end=" ")
  1. a1 b2
  2. a1 a2 b1 b2 c1 c2
  3. ab12
  4. a b c

b) a1 a2 b1 b2 c1 c2 — boucle imbriquée : pour chaque lettre (externe), on parcourt tous les chiffres (interne).

for lettre in "abc":
    for chiffre in "12":
        print(lettre + chiffre, end=" ")
a1 a2 b1 b2 c1 c2 

Question 8

Que vaut s après ce code ?

s = 0
for i in range(1, 5):
    s += i
  1. 4
  2. 5
  3. 10
  4. 15

c) 10 — on additionne 1 + 2 + 3 + 4 (pas 5, car range(1, 5) s’arrête à 4).

s = 0
for i in range(1, 5):
    s += i
print(s)
10

✏️ Exercice 9.1 — Table de multiplication

Écrivez un programme qui demande un nombre n et affiche sa table de multiplication de 1 à 10.

Exemple pour n = 3 :

3 × 1 = 3
3 × 2 = 6
...
3 × 10 = 30
n = int(input("Entrez un nombre : "))

# Afficher la table de n de 1 à 10
n = 7     # au lieu de input() pour la démo

for i in range(1, 11):
    print(f"{n} × {i} = {n * i}")
7 × 1 = 7
7 × 2 = 14
7 × 3 = 21
7 × 4 = 28
7 × 5 = 35
7 × 6 = 42
7 × 7 = 49
7 × 8 = 56
7 × 9 = 63
7 × 10 = 70

✏️ Exercice 9.2 — Somme des pairs

Calculez la somme de tous les nombres pairs entre 1 et 100.

somme = 0
# Parcourir 1 à 100, n'ajouter que les pairs
...

print("Somme :", somme)
somme = 0
for i in range(1, 101):
    if i % 2 == 0:
        somme += i
print("Somme :", somme)
Somme : 2550

Plus élégant : demander à range de faire le pas.

somme = 0
for i in range(2, 101, 2):     # 2, 4, 6, ..., 100
    somme += i
print("Somme :", somme)
Somme : 2550

Python permet de tout faire en une ligne :

print("Somme :", sum(range(2, 101, 2)))
Somme : 2550

✏️ Exercice 9.3 — Nombre mystère

Écrivez un jeu où l’ordinateur « pense » à un nombre entre 1 et 100, et l’utilisateur doit le deviner. À chaque essai :

  • Si le nombre saisi est trop petit, afficher "Trop petit".
  • Si trop grand, "Trop grand".
  • Si trouvé, "Bravo ! Trouvé en X essais" et sortir.
import random
mystere = random.randint(1, 100)

# Boucle while : demander jusqu'à trouver
import random

mystere = random.randint(1, 100)
essais = 0
trouve = False

while not trouve:
    essais += 1
    proposition = int(input("Votre nombre : "))

    if proposition < mystere:
        print("Trop petit")
    elif proposition > mystere:
        print("Trop grand")
    else:
        print(f"Bravo ! Trouvé en {essais} essais.")
        trouve = True
import random

mystere = random.randint(1, 100)
essais = 0

while True:            # boucle « infinie »
    essais += 1
    proposition = int(input("Votre nombre : "))

    if proposition == mystere:
        print(f"Bravo ! Trouvé en {essais} essais.")
        break
    elif proposition < mystere:
        print("Trop petit")
    else:
        print("Trop grand")

On remplace input par une liste d’essais prédéfinis pour faire tourner la démo :

import random

random.seed(42)        # pour reproductibilité
mystere = random.randint(1, 100)
propositions = [50, 75, 90, 82, 85, 83]   # essais simulés

print(f"Le mystère est {mystere}")
essais = 0
for p in propositions:
    essais += 1
    if p < mystere:
        print(f"Essai {essais}: {p} → Trop petit")
    elif p > mystere:
        print(f"Essai {essais}: {p} → Trop grand")
    else:
        print(f"Essai {essais}: {p} → Bravo ! Trouvé en {essais} essais.")
        break
Le mystère est 82
Essai 1: 50 → Trop petit
Essai 2: 75 → Trop petit
Essai 3: 90 → Trop grand
Essai 4: 82 → Bravo ! Trouvé en 4 essais.

✏️ Exercice 9.4 — Pyramide d’étoiles

Affichez une pyramide d’étoiles de n lignes. Pour n = 5 :

*
* *
* * *
* * * *
* * * * *
n = 5

# Deux boucles imbriquées : une pour les lignes, une pour les étoiles
n = 5

for ligne in range(1, n + 1):
    for etoile in range(ligne):
        print("*", end=" ")
    print()         # retour à la ligne après chaque ligne
* 
* * 
* * * 
* * * * 
* * * * * 
n = 5

for ligne in range(1, n + 1):
    espaces = " " * (n - ligne)
    etoiles = "* " * ligne
    print(espaces + etoiles)
    * 
   * * 
  * * * 
 * * * * 
* * * * * 

À retenir

Points clés du chapitre
  1. for x in collection: parcourt chaque élément de la collection.
  2. range(n) → 0 à n-1 ; range(a, b) → a à b-1 ; range(a, b, pas).
  3. while cond: répète tant que la condition est vraie. Attention aux boucles infinies.
  4. break sort de la boucle, continue passe à l’itération suivante.
  5. En Python, on préfère parcourir directement une collection plutôt que range(len(...)).
  6. Les boucles imbriquées sont utiles mais coûteuses en performance (n² itérations).
  7. Variable de boucle (i) accessible après la boucle avec sa dernière valeur.

← Chapitre précédent : Les ensemblesChapitre suivant : Les fonctions natives →