Les boucles
Informatique — Python, chapitre 4
Répéter un traitement est la raison d’être d’un programme. Une opération appliquée à dix mille observations ne s’écrit pas dix mille fois : elle s’écrit une fois, dans une boucle.
Python en propose deux — for quand on sait combien de tours, while quand on ne le sait pas — et introduit ici une règle de syntaxe qui le distingue de tous les langages vus jusqu’à présent : l’indentation.
4.1 La boucle for
4.1.1 Parcourir une liste
Trois éléments obligatoires : le mot for, les deux points en fin de ligne, et le décalage de la ligne suivante.
Python n’a ni accolades ni end. C’est le décalage qui délimite le bloc à répéter.
for v in villes:
print(v) # dans la boucle
print("fini") # hors de la boucle : execute une seule foisUn décalage oublié provoque IndentationError. Un décalage mal placé ne provoque rien du tout — le code s’exécute, mais pas comme vous le pensiez.
La convention universelle est de quatre espaces. N’utilisez jamais de tabulations : mêlées à des espaces, elles produisent des erreurs incompréhensibles.
4.1.2 Parcourir des nombres avec range
range(5) produit 0, 1, 2, 3, 4 — cinq valeurs, à partir de 0, et 5 n’y est pas. C’est la même convention que les tranches du chapitre 2.
range ne crée pas la liste : il fabrique les valeurs une à une, à la demande. C’est pourquoi range(1000000) est instantané et ne consomme aucune mémoire. list(...) sert seulement à le rendre visible.
4.1.3 Accumuler un résultat
Le motif est toujours le même : initialiser avant la boucle, cumuler dedans, utiliser après.
4.2 Les compagnons indispensables de for
4.2.1 enumerate : la position et la valeur
for i in range(len(v))
for i in range(len(villes)): # a eviter
print(i, villes[i])
for i, v in enumerate(villes): # preferable
print(i, v)La seconde forme est plus courte, plus lisible, et supprime tout risque d’erreur d’indice. C’est l’une des marques d’un code Python idiomatique.
4.2.2 zip : parcourir deux listes en parallèle
zip s’arrête à la plus courte des deux listes, sans avertissement. Vérifiez que les longueurs correspondent.
4.2.3 Parcourir une chaîne, un dictionnaire
Toute structure contenant des éléments se parcourt de la même façon. Les dictionnaires du chapitre 7 également.
4.3 La boucle while
while convient quand le nombre de tours dépend du calcul lui-même — ici, le temps de doublement à 7 %.
i = 0
while i < 10:
print(i) # i n'augmente jamaisSi la condition ne devient jamais fausse, la boucle tourne indéfiniment et fige le navigateur ou la console.
Avant d’exécuter un while, vérifiez qu’une ligne à l’intérieur fait progresser la condition vers sa fin. En cas de blocage dans un terminal, Ctrl + C interrompt.
4.4 Sortir ou passer
break quitte la boucle, continue saute au tour suivant. Le premier sert typiquement à s’arrêter dès qu’on a trouvé ce qu’on cherchait.
4.5 Les boucles imbriquées
Chaque niveau ajoute un décalage. L’argument end="" de print empêche le retour à la ligne automatique.
Deux boucles imbriquées sur 1 000 éléments font un million de tours. Trois en font un milliard.
Sur des données de taille réelle, une boucle imbriquée est presque toujours le signe qu’il faut une autre approche — un dictionnaire (chapitre 7) ou une opération vectorisée NumPy (chapitre 8).
4.6 Boucle ou compréhension ?
Le chapitre précédent a introduit les compréhensions. Voici comment choisir.
| Situation | Écriture |
|---|---|
| transformer chaque élément | compréhension |
| filtrer selon un critère | compréhension |
| accumuler un total, un compteur | boucle |
| chaque tour dépend du précédent | boucle |
| plusieurs instructions par tour | boucle |
| afficher, écrire dans un fichier | boucle |
La compréhension construit une liste. Dès que le but est autre, la boucle s’impose.
4.7 Un exemple complet
Remarquez for ville, pib, chomage in donnees : chaque tuple est décomposé directement en trois variables. Et total_pib += pib est l’abréviation de total_pib = total_pib + pib.
À vous
Écrivez une boucle qui parcourt les notes, compte les reçus, et affiche pour chacune son numéro, sa valeur et sa mention.
recus = 0
for i, n in enumerate(notes, start=1):
if n >= 14:
mention = "bien"
elif n >= 10:
mention = "passable"
else:
mention = "insuffisant"
if n >= 10:
recus += 1
print(f"{i}. {n:>3} {mention}")
print(f"\n{recus} recus sur {len(notes)} ({recus/len(notes):.0%})")Le if / elif / else employé ici fait l’objet du chapitre suivant. enumerate(..., start=1) numérote à partir de 1, plus naturel pour un affichage.
Ce qu’il faut retenir
| Écriture | Effet |
|---|---|
for x in v: |
parcourir une liste, une chaîne, un tuple |
| quatre espaces | l’indentation délimite le bloc — jamais de tabulation |
range(5), range(2, 8), range(0, 20, 5) |
engendrer des nombres — fin exclue |
enumerate(v) |
indice et valeur — mieux que range(len(v)) |
enumerate(v, start=1) |
numéroter à partir de 1 |
zip(a, b) |
parcourir deux listes en parallèle |
while cond: |
répéter tant que — vérifier qu’elle progresse |
break, continue |
quitter la boucle, passer au tour suivant |
total += x |
abréviation de total = total + x |
for a, b in donnees: |
décomposer un tuple directement |
Le chapitre suivant est consacré au test : faire dépendre l’exécution d’une condition, comme le if employé dans l’exercice ci-dessus.