Les boucles for et range — exécuter un nombre de fois connu
Quand vous savez combien de fois répéter, une boucle for est le bon choix. Les trois formes de range, pourquoi la fin est exclue, et comment choisir entre for et while.
Comment voulez-vous apprendre ?
Le problème que nous résolvons
Au chapitre précédent, additionner de 1 à 5 demandait quatre lignes, dont deux ne servaient qu'à compter : une valeur de départ et un incrément. Oubliez l'incrément, et vous obtenez une boucle infinie.
Mais remarquez une chose à propos de ce genre de travail : on savait à l'avance combien de fois il allait s'exécuter. Cinq. Dans ce cas, il n'y a aucune raison de gérer le compteur soi-même — vous pouvez le confier à Python.
C'est exactement ce que fait une boucle for. Et comme le comptage ne dépend plus de vous, une boucle for sur un range ne peut pas devenir infinie d'elle-même — le nombre de passages est fixé au démarrage de la boucle. C'est son plus grand atout. (Il y a une exception : si vous parcourez une liste et ajoutez sans cesse des éléments à cette même liste dans la boucle, la boucle ne se termine jamais. Les listes arrivent au chapitre suivant.)
À la fin de ce chapitre, vous pourrez
- Exécuter du code un nombre connu de fois avec une boucle
for - Utiliser les trois formes de
range() - Expliquer pourquoi
range(1, 5)produit quatre nombres, et non cinq - Parcourir les caractères d'une chaîne de caractères
- Décider quelle boucle,
forouwhile, convient à une tâche donnée
Prérequis : Les boucles while — répéter tant qu'une condition reste vraie.
La forme la plus simple
for number in range(5):
print(number)0
1
2
3
4Trois lignes de travail en une seule, sans compteur à gérer. Lisez-la ainsi : « pour chacun des nombres que produit `range(5)`, exécuter le bloc une fois — et à chaque fois, placer ce nombre dans `number` ».
Deux choses sautent aux yeux immédiatement :
Elle commence à zéro, et 5 n'apparaît jamais — cinq nombres au total, mais de 0 à 4. C'est la même règle que Python applique partout : tout comme l'indice de fin est exclu dans une tranche, il l'est aussi dans un range.
Le nom number est votre choix. for i in range(5) convient tout aussi bien, et i est le nom conventionnel d'un compteur. Mais quand le nombre a un sens, donnez-lui un nom qui le décrit — for student_number in range(30) se comprend tout seul.
Les trois formes de range()
print("--- range(5) ---")
for i in range(5):
print(i, end=" ")
print()
print("--- range(2, 6) ---")
for i in range(2, 6):
print(i, end=" ")
print()
print("--- range(0, 10, 3) ---")
for i in range(0, 10, 3):
print(i, end=" ")
print()
print("--- range(5, 0, -1) ---")
for i in range(5, 0, -1):
print(i, end=" ")
print()--- range(5) ---
0 1 2 3 4
--- range(2, 6) ---
2 3 4 5
--- range(0, 10, 3) ---
0 3 6 9
--- range(5, 0, -1) ---
5 4 3 2 1Les règles :
range(stop)— commence à0, s'arrête avantstoprange(start, stop)— commence àstart, s'arrête avantstoprange(start, stop, step)— avance destepà chaque tour ; unstepnégatif compte à rebours
Vérifiez les deux derniers. range(0, 10, 3) donne 0 3 6 9 — le suivant serait 12, qui dépasse 10, donc on s'arrête. Et range(5, 0, -1) donne 5 4 3 2 1 — 0 n'apparaît jamais, car ici aussi la fin est exclue.
Pourquoi la fin est-elle exclue ? Parce que cela simplifie le calcul. Combien de nombres dansrange(0, 5)?5 - 0, donc cinq. Dansrange(3, 8)?8 - 3, donc cinq. On soustrait et on obtient le compte, sans se demander s'il faut ajouter un. Et deuxrangeplacés côte à côte —range(0, 5)etrange(5, 10)— n'oublient aucun nombre et n'en répètent aucun.
Quand on veut de un à dix
Cette erreur arrive assez souvent pour mériter sa propre section :
print("Wrong — stops at 9:")
for i in range(1, 10):
print(i, end=" ")
print()
print("Right — includes 10:")
for i in range(1, 11):
print(i, end=" ")
print()Wrong — stops at 9:
1 2 3 4 5 6 7 8 9
Right — includes 10:
1 2 3 4 5 6 7 8 9 10La règle en une ligne : écrivez comme stop un nombre de plus que le dernier nombre souhaité.
Accumuler — désormais, la méthode simple
total = 0
for number in range(1, 6):
total = total + number
print("Sum of 1 to 5:", total)Sum of 1 to 5: 15Comparez avec la version while de la même tâche : pas de compteur à créer, pas à incrémenter, aucun risque de boucle infinie. Seul l'accumulateur doit toujours être initialisé en dehors de la boucle, exactement comme avant.
Parcourir une chaîne de caractères
for ne parcourt pas seulement des nombres — il parcourt aussi une chaîne de caractères, caractère par caractère :
word = "Python"
for letter in word:
print(letter, end="-")
print()
vowel_count = 0
for letter in "programming":
if letter in "aeiou":
vowel_count = vowel_count + 1
print("Vowels:", vowel_count)P-y-t-h-o-n-
Vowels: 3Ici, range n'est pas nécessaire : for letter in word parcourt directement les caractères. C'est plus simple qu'un calcul sur les indices, et il n'y a aucune IndexError à craindre.
Quand vous avez besoin à la fois de l'indice et du caractère, il existe enumerate() ; il sera présenté dans le chapitre sur les listes.
break et continue fonctionnent aussi ici
Exactement comme dans un while :
for number in range(1, 20):
if number % 7 == 0:
print("First multiple of 7:", number)
breakFirst multiple of 7: 7Choisir entre for et while
Posez-vous une seule question : le nombre de répétitions est-il connu avant le début de la boucle ?
Si oui, for :
- Exécuter cinq fois
- Aller de 1 à 100
- Examiner chaque caractère d'un mot
- Traiter chaque élément d'une liste
Si non, while :
- Redemander jusqu'à ce que la saisie soit valide
- Continuer jusqu'à ce que la personne tape
quit - Lire tant qu'il reste des lignes dans un fichier
En cas de doute, choisissez for. La raison est simple : une boucle for sur un range ou sur une chaîne de caractères fixe est assurée de se terminer, ce qui n'est pas le cas d'une boucle while. Quand les deux conviendraient, la meilleure solution est celle qui laisse le moins de place aux erreurs.
Un exemple complet
multiplication.py :
# Print a multiplication table, then a small summary
number = int(input("Which table? "))
upto = int(input("Up to? "))
print()
print(f"--- Table of {number} ---")
total = 0
for i in range(1, upto + 1):
result = number * i
total = total + result
print(f"{number} x {i:2} = {result:4}")
print()
print(f"Rows : {upto}")
print(f"Sum : {total}")
print(f"Average : {total / upto:.2f}")Which table? 7
Up to? 5
--- Table of 7 ---
7 x 1 = 7
7 x 2 = 14
7 x 3 = 21
7 x 4 = 28
7 x 5 = 35
Rows : 5
Sum : 105
Average : 21.00Trois choses à remarquer. D'abord, range(1, upto + 1) — pour atteindre upto, il a fallu en écrire un de plus. Ensuite, {i:2} et {result:4} — dans une f-string, vous pouvez préciser la largeur qu'un nombre doit occuper, ce qui garde les colonnes alignées. Enfin, total démarre en dehors de la boucle et grandit à l'intérieur — le même accumulateur que précédemment.
Et posez-vous une question : que se passe-t-il si la personne répond 0 à Up to? ? range(1, 1) ne produit aucun nombre, donc la boucle ne s'exécute jamais — et alors total / upto divise par zéro. C'est la même leçon que dans le chapitre précédent : avant d'utiliser ce qu'une boucle a accumulé, vérifiez qu'elle a bien accumulé quelque chose.
En cas de problème
La dernière valeur manque range(1, 10) s'arrête à 9. Ajoutez un au stop : range(1, 11).
TypeError: 'float' object cannot be interpreted as an integer range() n'accepte que des nombres entiers (int). range(2.5) ou range(1, n / 2) ne fonctionneront pas — convertissez avec int(), ou divisez avec //.
SyntaxError: expected ':' Les deux-points à la fin de la ligne for sont absents.
IndentationError: expected an indented block after 'for' statement La ligne à l'intérieur de la boucle n'est pas indentée.
La boucle ne s'est jamais exécutée Le range est vide. range(5, 0) ne produit rien — pour compter à rebours, il faut le troisième argument : range(5, 0, -1).
Le total vaut 0 après la boucle La ligne total = 0 s'est glissée à l'intérieur de la boucle, si bien qu'elle se réinitialise à chaque passage. Elle doit se trouver en dehors.
Une variable créée dans la boucle est utilisée après celle-ci, mais lève une NameError Le range était vide, donc la boucle ne s'est jamais exécutée et la variable n'a jamais été créée. Donnez-lui une valeur de départ avant la boucle.
Étape 4 sur 6 — Prédire
Vérifiez votre compréhension
Qu'est-ce qui est affiché par cette boucle ?
for i in range(1, 5):
print(i, end=" ")- A1 2 3 4 5
- B1 2 3
- C0 1 2 3 4
- D1 2 3 4
Le troisième argument définit le pas. Quelle est la sortie ?
for i in range(0, 10, 3):
print(i, end=" ")- A3 6 9
- B0 3 6 9
- C0 1 2 3 4 5 6 7 8 9
- D0 3 6 9 12
L'intention était la somme de 1 à 10, soit 55. Le programme affiche 45. Pourquoi ?
total = 0
for number in range(1, 10):
total = total + number
print("Sum of 1 to 10:", total)- A`total` est initialisé en dehors de la boucle alors qu'il devrait l'être à l'intérieur
- BUtiliser une boucle `while` au lieu de `for` donnerait le bon résultat
- CIl faudrait `total + i` au lieu de `total + number`
- D`range(1, 10)` s'arrête à `9` et laisse de côté `10` — il faut `range(1, 11)`
Répondre nécessite un compte
Connectez-vous pour vérifier vos réponses
Les questions sont ci-dessus, et les résoudre de tête est ce qui compte vraiment. Connectez-vous pour voir les réponses, les explications et les indices à trois niveaux.
À vous de jouer
Écrivez un fichier nommé stars.py qui prend un nombre et affiche un triangle. Pour 5 :
*
**
***
****
*****Ajoutez ensuite ces trois éléments :
- Affichez le nombre total d'étoiles en bas (15 pour une saisie de 5)
- Affichez aussi le triangle à l'envers — cinq en haut, un en bas
- Affichez une version qui saute les lignes de numéro pair (utilisez
continue)
Il existe un moyen simple de vérifier le premier point : calculez à la main la somme de 1 à 5 et voyez si votre programme est d'accord. Et rappelez-vous "*" * i ? Construire une ligne d'étoiles ne demande pas de boucle à l'intérieur de la boucle.
Étape 6 sur 6
Défi — le quiz du chapitre
Dix questions, de la plus facile à la plus difficile. Les dernières sont difficiles exprès.
Connectez-vous pour faire le quiz