Retour au cours

backend / python

Boucles for et while

Leçon 31 exercice

Explication

Ce que vous allez apprendre

  • Choisir entre for et while selon que le nombre d'itérations est connu à l'avance ou non
  • Utiliser enumerate() et zip() pour éviter de gérer des indices à la main
  • Contrôler précisément le flux d'une boucle avec break, continue et la clause else
  • Repérer pourquoi modifier une liste pendant qu'on la parcourt cause des bugs difficiles à voir
  • Écrire une boucle while True sûre, avec une condition de sortie garantie

Dans quel contexte ?

Un développeur écrit une fonction trouver_utilisateur_actif(utilisateurs) qui doit parcourir une liste et retourner le premier utilisateur dont statut == "actif", ou signaler qu'aucun n'a été trouvé. Sans la clause else d'une boucle for, il devrait introduire une variable trouve = False supplémentaire juste pour savoir, après coup, si la recherche a abouti — la clause else rend ce code plus court et plus clair.

Répéter sans se répéter

Écrire vingt fois la même instruction pour traiter vingt éléments serait absurde. Les boucles existent pour exécuter un bloc de code plusieurs fois sans dupliquer le code source. Python propose deux boucles aux usages différents : for parcourt une collection élément par élément (on sait à l'avance sur quoi on itère), et while répète tant qu'une condition reste vraie (on ne sait pas forcément combien de fois).

BoucleUtiliser quand...Exemple
forLe nombre d'éléments à parcourir est connufor ligne in fichier:
whileOn répète jusqu'à une condition, sans savoir combien de foiswhile connexion.en_attente():
while True + breakLa sortie dépend d'un événement interne à la boucleLire un flux jusqu'à un signal d'arrêt

for en Python n'est pas un compteur

Dans beaucoup de langages, une boucle for manipule un indice numérique. En Python, for element in collection parcourt directement les éléments, pas des indices. Si vous avez besoin de l'indice, enumerate() vous l'offre proprement plutôt que de le gérer à la main avec un compteur externe. De même, zip() permet de parcourir plusieurs séquences en parallèle sans jongler avec des indices.

Contrôler le flux à l'intérieur

break arrête complètement la boucle, continue saute uniquement à l'itération suivante. Une subtilité peu connue mais élégante : une boucle peut avoir une clause else, exécutée uniquement si elle s'est terminée normalement, sans break. C'est un outil précieux pour des algorithmes de recherche : si j'ai parcouru toute la liste sans rien trouver, alors...

Piège fréquent

Supprimer des éléments d'une liste avec for item in liste: liste.remove(item) saute silencieusement certains éléments, car Python déplace les indices restants pendant que la boucle avance. La solution sûre : parcourir une copie (for item in liste[:]) ou construire une nouvelle liste filtrée.

Pièges fréquents

Modifier une liste pendant qu'on la parcourt avec un for peut provoquer des comportements imprévisibles (des éléments sautés). Et une boucle while True mal maîtrisée devient vite une boucle infinie si la condition de sortie n'est jamais atteinte.

Après avoir appris à choisir (leçon précédente) et maintenant à répéter, vous avez les deux briques de contrôle de flux fondamentales. Les prochaines leçons s'appuient constamment dessus, notamment pour construire des listes et des dictionnaires.

Commandes & code

Boucles for et while

Repeter des instructions, avec controle fin du flux.

python
# for sur un iterable
fruits = ["pomme", "banane", "cerise"]
for fruit in fruits:
    print(fruit)

# range() : sequence d'entiers, sans creer de liste en memoire
for i in range(5):            # 0, 1, 2, 3, 4
    print(i)

for i in range(2, 10, 2):     # start, stop, step -> 2, 4, 6, 8
    print(i)

# enumerate() : obtenir l'index sans compteur manuel
for index, fruit in enumerate(fruits, start=1):
    print(f"{index}. {fruit}")

# zip() : parcourir plusieurs iterables en parallele
noms = ["Ana", "Bo", "Cy"]
scores = [92, 78, 85]
for nom, score in zip(noms, scores):
    print(f"{nom} : {score}")

# while : tant qu'une condition est vraie
compteur = 0
while compteur < 3:
    print(f"Iteration {compteur}")
    compteur += 1

# break / continue
for n in range(10):
    if n == 5:
        break               # sort de la boucle
    if n % 2 == 0:
        continue            # passe a l'iteration suivante
    print(n)                # affiche 1, 3

# clause else sur une boucle (execute si pas de break) : peu connue mais utile
def contient_premier(liste):
    for n in liste:
        if n < 2:
            continue
        for d in range(2, int(n ** 0.5) + 1):
            if n % d == 0:
                break
        else:
            return n          # aucun diviseur trouve : n est premier
    return None

print(contient_premier([4, 6, 8, 9, 11, 15]))   # 11

# Boucle infinie controlee : pattern courant pour lire un flux
def lire_lignes(source):
    while True:
        ligne = next(source, None)
        if ligne is None:
            break
        yield ligne.strip()

# Parcours inverse et par pas
for i in range(10, 0, -1):
    print(i, end=" ")
print()

liste = list(range(20))
print(liste[::2])       # un element sur deux
print(liste[::-1])      # inversee

Résumé

  • for ... in ... parcourt un iterable, while boucle sur une condition.
  • enumerate() et zip() evitent les compteurs manuels et les indices.
  • break/continue controlent le flux ; else sur une boucle s'execute seulement sans break.

Exercices pratiques

1 disponible
1

Mission : corriger un script de nettoyage qui saute des lignes

Objectif : Diagnostiquer pourquoi une boucle qui modifie une liste en la parcourant saute des éléments, puis réécrire un algorithme de recherche avec la clause else.

Contexte

Un script doit nettoyer une liste de commandes en supprimant celles marquées "annulée", avec for commande in commandes: commandes.remove(commande) si elle est annulée. Le résultat final contient encore des commandes annulées, alors que le développeur jure avoir bien parcouru toute la liste.

Tu dois expliquer ce bug classique, réécrire le nettoyage correctement, puis utiliser la clause else d'une boucle for pour un algorithme de recherche.

Résoudre l’exercice →