Vidéo 18 : La boucle for¶
Boucle for
: introduction¶
Le code suivant présente un exemple d’utilisation d’une boucle for :
for.py
1 2 3 | for i in range(0, 4):
print("Bonjour !")
print("---------")
|
4 5 6 7 8 9 10 11 | Bonjour !
---------
Bonjour !
---------
Bonjour !
---------
Bonjour !
---------
|
Les lignes 1-3 constituent une instruction for
. On observe (lignes 4-11) que le message Bonjour !
suivi du séparateur ---------
est affiché 4 fois. Si on changeait la valeur 4 à la ligne 1 en la valeur 5 le message serait répété 5 fois.
Ici, la boucle for
a permis de répéter une action un certain nombre de fois.
Déroulement d’une instruction for
¶
- À la ligne 1, la présence de
range(0, 4)
permet d’itérer sur les entiers de 0 à 4, l’entier 4 étant exclu : 0, 1, 2 et 3. Les entiers vont être générés les uns à la suite des autres. - Quand la boucle
for
commence, l’indicei
vaut le premier élément généré (ici 0). - L’exécution entre ensuite dans la ligne 2, effectue l’action d’affichage puis idem à la ligne 3
- Une fois les deux affichages effectués, l’exécution revient à la ligne 1. Comme pour l’instant
i = 0
, il reste encore des entiers à générer, donc, le principe même de l’instructionfor
veut quei
passe à l’élément suivant, iei = 1
puis les instructions d’affichage des lignes 2-3 s’exécutent à nouveau. - L’exécution se poursuit ainsi jusqu’à ce que
i
passe de 2 à 3. Lorsquei
vaut 3, un affichage se fait encore et lorsque l’exécution repasse ligne 1, tous les entiers ont été générés : la conséquence est que la boucle s’arrête.
Édition d’une boucle for
¶
On reprend le code for.py
, on détaille la syntaxe d’une boucle for
et le vocabulaire associé :
for.py
1 2 3 | for i in range(0, 4):
print("Bonjour !")
print("---------")
|
- Ligne 1 :
for
etin
sont des mots-clés de Python et sont obligatoires à toute bouclefor
. - Ligne 1 :
i
est la variable de contrôle de la bouclefor
. D’autres noms fréquents de variables sontj
,k
mais tout nom de variable commetoto
conviendrait. Ici, la variable de contrôle parcourt la succession des entiers générés parrange(0,4)
. - Ligne 1 : le séparateur deux-points (:) à la fin est obligatoire
- Ligne 1 :
range
est une fonction built-in du langage Python qui sert à générer des entiers consécutifs. - Ligne 1 : la partie qui commence à
for
jusqu’aux deux-points est appelé l”en-tête de la bouclefor
- Lignes 2-3 : le corps de la boucle. Les instructions du corps de la boucle
for
sont celles qui vont être répétées tant quei
est généré. Ce n’est pas le cas ici mais en général, le corps de la boucle dépend de la variablei
. Le corps de la bouclefor
est dans l’immense majorité des cas, situé une ligne sous l’en-tête, autrement dit un saut de ligne dans le code-source est effectué après l’en-tête. - Lignes 2-3 : le corps de la boucle
for
est toujours indenté et suit la règle générale d’indentation en Python. - Lignes 1-3 : les trois lignes constituent une seule et même instruction, dite « instruction
for
».
Le terme de boucle vient du fait que lorsque l’exécution est parvenue à la fin du corps de la boucle, l’exécution retourne à l’en-tête de la boucle.
Action qui dépend de la variable de la boucle¶
Dans le code for.py
, l’action effectuée à chaque étape du parcours de la liste ne dépendait pas de la variable i
. En fait, assez souvent, l’action effectuée dans le corps de la boucle dépendra de la variable de contrôle. Voici un exemple :
1 2 | for i in range(0, 5):
print("Message n°", i+1, ":", "Bonjour !")
|
qui affiche
1 2 3 4 5 | Message n° 1 : Bonjour !
Message n° 2 : Bonjour !
Message n° 3 : Bonjour !
Message n° 4 : Bonjour !
Message n° 5 : Bonjour !
|
On observe que chaque message affiché est différent du précédent par le numéro qu’il affiche : en effet, le corps de la boucle (ligne 2) dépend de i
qui varie à chaque tour de boucle.
Répéter une action \(n\) fois avec une boucle for
¶
La boucle for et la fonction range permettent typiquement de répéter une action n
fois où n
est fixé avant le démarrage de la boucle.
Par exemple, soit à afficher un carré de côté 10 comme ci-dessous :
1 2 3 4 5 6 7 8 9 10 | * * * * * * * * * *
* * * * * * * * * *
* * * * * * * * * *
* * * * * * * * * *
* * * * * * * * * *
* * * * * * * * * *
* * * * * * * * * *
* * * * * * * * * *
* * * * * * * * * *
* * * * * * * * * *
|
L’affichage consiste en la répétition 10 fois de l’affichage d’une ligne de la forme
1 | * * * * * * * * * *
|
où les étoiles sont séparés par une espace.
Le code Python pourrait être :
1 2 3 | z="* * * * * * * * * *"
for i in range(10):
print(z)
|
De même, soit à afficher les 10 premiers multiples de 5 en commençant par 75 :
\(75\), \(75 +5=80,\) \(75+10=85\), etc.
Donc, un code répondant à la question est le suivant :
1 2 3 | d = 75
for i in range(10):
print(d + 5 * i)
|
4 5 6 7 8 9 10 11 12 13 | 75
80
85
90
95
100
105
110
115
120
|
- Ligne 2 : typiquement, on utilise range(10) pour exprimer qu’une action va être exécutée 10 fois. Le nombre de répétitions (ici 10) est connu avant d’effectuer la boucle
for
. - Ligne 3 : l’action (d’afficher le multiple) est à effectuer 10 fois.
Règle : Si un programme répète une action et si le nombre de répétitions à effectuer est connu à l’avance, le programme utilise une boucle for
avec la syntaxe suivante :
1 2 | for i in range(n):
# action a coder ICI
|
Itérer sur des entiers consécutifs¶
La fonction built-in range
permet de générer automatiquement des entiers consécutifs, comme les entiers 6, 7, 8 et 9 :
1 2 3 | r=range(6, 10)
for i in r:
print(i)
|
4 5 6 7 | 6
7
8
9
|
En pratique, on n’utilise pas la variable intermédiaire r
ci-dessus et on écrit plutôt :
1 2 | for i in range(6, 10):
print(i)
|
Bien observer que le deuxième argument de la fonction range
(dans l’exemple, c’est 10) est exclu des nombres générés. Toutefois, le nombre d’entiers générés par range(a,b)
est \(\mathtt{b-a}\) (en supposant que \(\mathtt{a\leq b}\)).
Si \(\mathtt{n\geq 0}\) est un entier, l’expression range(n)
est un raccourci syntaxique pour range(0,n)
:
1 2 | for i in range(3):
print(i)
|
3 4 5 | 0
1
2
|
Affichage sur une même ligne et boucle for
¶
Soit à réaliser avec une boucle for l’affichage suivant :
----------------
0 1 2 3 4 5 6 7 8 9
----------------
Pour éviter le saut de ligne après l’affichage de chaque entier et pour séparer chaque nombre du précédent d’une espace, on utilise l’argument nommé end = " "
:
1 2 3 4 5 | print("----------------")
for i in range(10):
print(i, end = " ")
print()
print("----------------")
|
6 7 8 | ----------------
0 1 2 3 4 5 6 7 8 9
----------------
|
- Ligne 7 : chaque entier est séparé du précédent par un espace. Aucun saut de ligne n’est effectué lors de l’exécution de la boucle.
- Ligne 4 : permet d’effectuer un saut de ligne entre le dernier chiffre affiché (ligne 7) et la ligne formée de pointillés (ligne 8)
Omettre l’appel à print
en sortie de boucle provoque un affichage incorrect :
1 2 3 4 5 | print("----------------")
for i in range(10):
print(i, end = " ")
print()
print("----------------")
|
6 7 8 | ----------------
0 1 2 3 4 5 6 7 8 9
----------------
|
Pour bien comprendre la rôle de end=" "
dans print(i, end=" ")
, il suffit d’observer le résultat du code ci-dessous où le end=" "
est remplacé par, par exemple, la chaîne end="xxx"
:
1 2 3 4 5 | print("----------------")
for i in range(10):
print(i, end="xxx")
print()
print("----------------")
|
6 7 8 | ----------------
0xxx1xxx2xxx3xxx4xxx5xxx6xxx7xxx8xxx9xxx
----------------
|
Calcul d’une somme¶
On se donne un entier \(n\geq 0\), on lance un dé \(n\) fois et on fait la somme des numéros lus. Par exemple, pour \(n=5\), les coups de dés sont
6, 1, 1, 5, 6
dont la somme va être \(6 + 1 + 1 + 5 + 6 = 19\).
Pour effectuer ce genre de somme, il faut répéter \(n\) fois :
- le tirage du dé,
- l’ajout du numéro
voilà pourquoi on a besoin d’une boucle for
. La somme à calculer est placée dans une variable s
qui au départ vaut 0 et qui à chaque étape de la boucle for
augmente du numéro tiré. Voici comment évolue s
si \(n=5\) et si le tirage est 6, 1, 1, 5, 6 :
Tirage du dé | Valeur de s |
Néant | 0 |
6 | 6 |
1 | 7 |
1 | 8 |
5 | 13 |
6 | 19 |
D’où le code ci-dessous :
1 2 3 4 5 6 7 8 9 10 11 | from random import randint
n=5
s=0
for i in range(n):
de = randint(1,6)
print(de)
s = s + de
print("Valeur de s :", s)
|
12 13 14 15 16 17 | 6
1
1
5
6
Valeur de s : 19
|
- Ligne 1 : on a besoin d’importer
randint
pour tirer le dé - Ligne 3 : le nombre de lancer de dé.
- Ligne 4 : on initialise la somme à 0 (on a encore rien ajouté) et non pas à la première valeur du tirage, cela donne un code plus simple.
- Ligne 7-8 : les deux actions à répéter : le tirage du dé, l’ajout du numéro. A chaque étape de la boucle,
s
contient la somme de toutes les valeurs tirés depuis le début de l’expérience. - Ligne 11 : une fois les
n
dés lancés,s
contient la somme de tous les numéros.