Boucles Python "while" (Itération indéfinie)
Iteration signifie exécuter le même bloc de code encore et encore, potentiellement plusieurs fois. Une structure de programmation qui implémente l'itération est appelée unloop.
En programmation, il existe deux types d'itération, indéfinie et définie:
-
Avecindefinite iteration, le nombre d'exécutions de la boucle n'est pas spécifié explicitement à l'avance. Au contraire, le bloc désigné est exécuté à plusieurs reprises tant qu'une certaine condition est remplie.
-
Avecdefinite iteration, le nombre de fois où le bloc désigné sera exécuté est spécifié explicitement au moment où la boucle démarre.
Dans ce tutoriel, vous allez:
-
Découvrez la boucle
while
, la structure de contrôle Python utilisée pour une itération indéfinie -
Découvrez comment rompre une boucle ou itérer une boucle prématurément
-
Explorez des boucles infinies
Lorsque vous avez terminé, vous devez avoir une bonne compréhension de l'utilisation de l'itération indéfinie en Python.
Free Bonus:Click here to get our free Python Cheat Sheet qui vous montre les bases de Python 3, comme travailler avec des types de données, des dictionnaires, des listes et des fonctions Python.
__ Take the Quiz: Testez vos connaissances avec notre quiz interactif «Python» tout en «Boucles». À la fin, vous recevrez un score afin que vous puissiez suivre vos progrès d'apprentissage au fil du temps:
La bouclewhile
Voyons comment l'instructionwhile
de Python est utilisée pour construire des boucles. Nous allons commencer simple et embellir au fur et à mesure.
Le format d'une boucle rudimentairewhile
est illustré ci-dessous:
while :
<statement(s)>
représente le bloc à exécuter à plusieurs reprises, souvent appelé le corps de la boucle. Ceci est indiqué par une indentation, tout comme dans une instructionif
.
Remember: Toutes les structures de contrôle en Python utilisent l'indentation pour définir les blocs. Voir la discussion surgrouping statements dans le didacticiel précédent pour la revoir.
L'expression de contrôle,<expr>
, implique généralement une ou plusieurs variables qui sont initialisées avant le démarrage de la boucle, puis modifiées quelque part dans le corps de la boucle.
Lorsqu'une bouclewhile
est rencontrée,<expr>
est d'abord évalué enBoolean context. S'il est vrai, le corps de la boucle est exécuté. Ensuite,<expr>
est vérifié à nouveau, et s'il est toujours vrai, le corps est à nouveau exécuté. Cela continue jusqu'à ce que<expr>
devienne faux, à quel point l'exécution du programme passe à la première instruction au-delà du corps de la boucle.
Considérez cette boucle:
>>>
1 >>> n = 5
2 >>> while n > 0:
3 ... n -= 1
4 ... print(n)
5 ...
6 4
7 3
8 2
9 1
10 0
Voici ce qui se passe dans cet exemple:
-
n
est initialement5
. L'expression dans l'en-tête de l'instructionwhile
sur la ligne 2 estn > 0
, ce qui est vrai, donc le corps de la boucle s'exécute. À l'intérieur du corps de la boucle sur la ligne 3,n
est décrémenté de1
à4
, puis imprimé. -
Une fois le corps de la boucle terminé, l'exécution du programme revient en haut de la boucle à la ligne 2 et l'expression est à nouveau évaluée. C'est toujours vrai, donc le corps s'exécute à nouveau et
3
est imprimé. -
Cela continue jusqu'à ce que
n
devienne0
. À ce stade, lorsque l'expression est testée, elle est fausse et la boucle se termine. L'exécution reprendrait à la première instruction suivant le corps de la boucle, mais il n'y en a pas dans ce cas.
Notez que l'expression de contrôle de la bouclewhile
est testée en premier, avant que quoi que ce soit d'autre ne se produise. Si c'est faux pour commencer, le corps de la boucle ne sera jamais exécuté du tout:
>>>
>>> n = 0
>>> while n > 0:
... n -= 1
... print(n)
...
Dans l'exemple ci-dessus, lorsque la boucle est rencontrée,n
est0
. L'expression de contrôlen > 0
est déjà fausse, donc le corps de la boucle ne s'exécute jamais.
Voici une autre bouclewhile
impliquant une liste, plutôt qu'une comparaison numérique:
>>>
>>> a = ['foo', 'bar', 'baz']
>>> while a:
... print(a.pop(-1))
...
baz
bar
foo
Quand unlist is evaluated in Boolean context, il est vrai s'il contient des éléments et faux s'il est vide. Dans cet exemple,a
est vrai tant qu'il contient des éléments. Une fois que tous les éléments ont été supprimés avec la méthode.pop()
et que la liste est vide,a
est faux et la boucle se termine.
Les instructions Pythonbreak
etcontinue
Dans chaque exemple que vous avez vu jusqu'à présent, le corps entier de la bouclewhile
est exécuté à chaque itération. Python fournit deux mots clés qui mettent fin prématurément à une itération de boucle:
-
L'instruction Python
break
termine immédiatement une boucle entièrement. L'exécution du programme passe à la première instruction suivant le corps de la boucle. -
L'instruction Python
continue
termine immédiatement l'itération de boucle actuelle. L'exécution passe en haut de la boucle et l'expression de contrôle est réévaluée pour déterminer si la boucle s'exécutera à nouveau ou se terminera.
La distinction entrebreak
etcontinue
est illustrée dans le diagramme suivant:
Voici un fichier de script appelébreak.py
qui illustre l'instructionbreak
:
1 n = 5
2 while n > 0:
3 n -= 1
4 if n == 2:
5 break
6 print(n)
7 print('Loop ended.')
L'exécution debreak.py
à partir d'un interpréteur de ligne de commande produit la sortie suivante:
C:\Users\john\Documents>python break.py
4
3
Loop ended.
Lorsquen
devient2
, l'instructionbreak
est exécutée. La boucle est complètement terminée et l'exécution du programme passe à l'instructionprint()
à la ligne 7.
Le script suivant,continue.py
, est identique sauf pour une instructioncontinue
à la place desbreak
:
1 n = 5
2 while n > 0:
3 n -= 1
4 if n == 2:
5 continue
6 print(n)
7 print('Loop ended.')
La sortie decontinue.py
ressemble à ceci:
C:\Users\john\Documents>python continue.py
4
3
1
0
Loop ended.
Cette fois, lorsquen
est2
, l'instructioncontinue
provoque la fin de cette itération. Ainsi,2
n’est pas imprimé. L'exécution revient en haut de la boucle, la condition est réévaluée et elle est toujours vraie. La boucle reprend et se termine lorsquen
devient0
, comme précédemment.
La clauseelse
Python autorise une clauseelse
optionnelle à la fin d'une bouclewhile
. Il s'agit d'une fonctionnalité unique de Python, introuvable dans la plupart des autres langages de programmation. La syntaxe est indiquée ci-dessous:
while :
else:
Les<additional_statement(s)>
spécifiés dans la clauseelse
seront exécutés lorsque la bouclewhile
se terminera.
À propos de maintenant, vous vous demandez peut-être: «En quoi est-ce utile?» Vous pouvez accomplir la même chose en plaçant ces instructions immédiatement après la bouclewhile
, sans leselse
:
while :
Quelle est la différence?
Dans ce dernier cas, sans la clauseelse
,<additional_statement(s)>
sera exécuté après la fin de la bouclewhile
, quoi qu'il arrive.
Lorsque<additional_statement(s)>
sont placés dans une clauseelse
, ils ne seront exécutés que si la boucle se termine «par épuisement» - c'est-à-dire si la boucle se répète jusqu'à ce que la condition de contrôle devienne fausse. Si la boucle est quittée par une instructionbreak
, la clauseelse
ne sera pas exécutée.
Prenons l'exemple suivant:
>>>
>>> n = 5
>>> while n > 0:
... n -= 1
... print(n)
... else:
... print('Loop done.')
...
4
3
2
1
0
Loop done.
Dans ce cas, la boucle s'est répétée jusqu'à ce que la condition soit épuisée:n
est devenu0
, doncn > 0
est devenu faux. Parce que la boucle a vécu sa vie naturelle, pour ainsi dire, la clauseelse
a été exécutée. Observez maintenant la différence ici:
>>>
>>> n = 5
>>> while n > 0:
... n -= 1
... print(n)
... if n == 2:
... break
... else:
... print('Loop done.')
...
4
3
2
Cette boucle se termine prématurément avecbreak
, donc la clauseelse
n’est pas exécutée.
Il peut sembler que la signification du motelse
ne correspond pas tout à fait à la bouclewhile
aussi bien qu’à l’instructionif
. Guido van Rossum, le créateur de Python, a en fait déclaré que, s’il avait à recommencer, il laisserait la clauseelse
de la bouclewhile
hors du langage.
L'une des interprétations suivantes pourrait aider à la rendre plus intuitive:
-
Considérez l'en-tête de la boucle (
while n > 0
) comme une instructionif
(if n > 0
) qui est exécutée encore et encore, avec la clauseelse
finalement exécutée lorsque la condition devient faux. -
Pensez à
else
comme s'il s'agissait denobreak
, en ce que le bloc qui suit est exécuté s'il n'y a pas debreak
.
Si vous ne trouvez aucune de ces interprétations utile, n'hésitez pas à les ignorer.
Quand une clauseelse
sur une bouclewhile
peut-elle être utile? Une situation courante est si vous recherchez une liste pour un élément spécifique. Vous pouvez utiliserbreak
pour quitter la boucle si l’élément est trouvé, et la clauseelse
peut contenir du code destiné à être exécuté si l’élément n’est pas trouvé:
>>>
>>> a = ['foo', 'bar', 'baz', 'qux']
>>> s = 'corge'
>>> i = 0
>>> while i < len(a):
... if a[i] == s:
... # Processing for item found
... break
... i += 1
... else:
... # Processing for item not found
... print(s, 'not found in list.')
...
corge not found in list.
Note: Le code ci-dessus est utile pour illustrer le concept, mais il est en fait très peu probable que vous recherchiez une liste de cette façon.
Tout d'abord, les listes sont généralement traitées avec une itération définie, pas une bouclewhile
. L'itération définie est traitée dans le prochain didacticiel de cette série.
Deuxièmement, Python fournit des moyens intégrés de rechercher un élément dans une liste. Vous pouvez utiliser l'opérateurin
:
>>>
>>> if s in a:
... print(s, 'found in list.')
... else:
... print(s, 'not found in list.')
...
corge not found in list.
La méthodelist.index()
fonctionnerait également. Cette méthode déclenche une exceptionValueError
si l'élément n'est pas trouvé dans la liste, vous devez donc comprendre la gestion des exceptions pour l'utiliser. En Python, vous utilisez une instructiontry
pour gérer une exception. Un exemple est donné ci-dessous:
>>>
>>> try:
... print(a.index('corge'))
... except ValueError:
... print(s, 'not found in list.')
...
corge not found in list.
Vous découvrirez la gestion des exceptions plus loin dans cette série.
Une clauseelse
avec une bouclewhile
est un peu bizarre, rarement vue. Mais n'hésitez pas si vous trouvez une situation dans laquelle vous pensez que cela ajoute de la clarté à votre code!
Boucles Infinies
Supposons que vous écriviez une bouclewhile
qui ne se termine théoriquement jamais. Ça a l'air bizarre, non?
Considérons cet exemple:
>>>
>>> while True:
... print('foo')
...
foo
foo
foo
.
.
.
foo
foo
foo
KeyboardInterrupt
Traceback (most recent call last):
File "", line 2, in
print('foo')
Ce code a été terminé par [.keys] #Ctrl [.kbd .key-c] # C ##, qui génère une interruption depuis le clavier. Sinon, cela aurait continué sans fin. De nombreuses lignes de sortie `+ foo` ont été supprimées et remplacées par des points de suspension verticaux dans la sortie affichée.
Clairement,True
ne sera jamais faux, ou nous avons tous de très gros problèmes. Ainsi,while True:
initie une boucle infinie qui fonctionnera théoriquement pour toujours.
Peut-être que cela ne ressemble pas à quelque chose que vous voudriez faire, mais ce modèle est en fait assez courant. Par exemple, vous pouvez écrire du code pour un service qui démarre et s'exécute pour toujours en acceptant les demandes de service. «Pour toujours» dans ce contexte signifie jusqu'à ce que vous le fermiez, ou jusqu'à la mort par la chaleur de l'univers, selon la première éventualité.
Plus prosaïquement, rappelez-vous que les boucles peuvent être rompues avec l'instructionbreak
. Il peut être plus simple de terminer une boucle en fonction de conditions reconnues dans le corps de la boucle, plutôt qu'en fonction d'une condition évaluée en haut.
Voici une autre variante de la boucle illustrée ci-dessus qui supprime successivement des éléments d'une liste à l'aide de.pop()
jusqu'à ce qu'elle soit vide:
>>>
>>> a = ['foo', 'bar', 'baz']
>>> while True:
... if not a:
... break
... print(a.pop(-1))
...
baz
bar
foo
Lorsquea
devient vide,not a
devient vrai et l'instructionbreak
quitte la boucle.
Vous pouvez également spécifier plusieurs instructionsbreak
dans une boucle:
while True:
if : # One condition for loop termination
break
...
if : # Another termination condition
break
...
if : # Yet another
break
Dans des cas comme celui-ci, où il y a plusieurs raisons de terminer la boucle, il est souvent plus propre debreak
à partir de plusieurs emplacements différents, plutôt que d'essayer de spécifier toutes les conditions de terminaison dans l'en-tête de la boucle.
Les boucles infinies peuvent être très utiles. N'oubliez pas que vous devez vous assurer que la boucle est rompue à un moment donné, afin qu'elle ne devienne pas vraiment infinie.
Boucleswhile
imbriquées
En général, les structures de contrôle Python peuvent être imbriquées les unes dans les autres. Par exemple, les instructions conditionnellesif
/elif
/else
peuvent être imbriquées:
if age < 18:
if gender == 'M':
print('son')
else:
print('daughter')
elif age >= 18 and age < 65:
if gender == 'M':
print('father')
else:
print('mother')
else:
if gender == 'M':
print('grandfather')
else:
print('grandmother')
De même, une bouclewhile
peut être contenue dans une autre bouclewhile
, comme illustré ici:
>>>
>>> a = ['foo', 'bar']
>>> while len(a):
... print(a.pop(0))
... b = ['baz', 'qux']
... while len(b):
... print('>', b.pop(0))
...
foo
> baz
> qux
bar
> baz
> qux
Une instructionbreak
oucontinue
trouvée dans des boucles imbriquées s'applique à la boucle englobante la plus proche:
while :
statement
statement
while :
statement
statement
break # Applies to while : loop
break # Applies to while : loop
De plus, les boucleswhile
peuvent être imbriquées dans les instructionsif
/elif
/else
, et vice versa:
if :
statement
while :
statement
statement
else:
while :
statement
statement
statement
while :
if :
statement
elif :
statement
else:
statement
if :
statement
En fait, toutes les structures de contrôle Python peuvent être entremêlées les unes aux autres selon vos besoins. C'est comme ça que ça devrait être. Imaginez à quel point ce serait frustrant s'il y avait des restrictions inattendues comme «Une bouclewhile
ne peut pas être contenue dans une instructionif
» ou «les boucleswhile
ne peuvent être imbriquées les unes dans les autres qu'à la plupart des quatre profonds. Vous auriez du mal à vous souvenir de tous.
Les limitations numériques ou logiques apparemment arbitraires sont considérées comme un signe de mauvaise conception du langage de programme. Heureusement, vous n'en trouverez pas beaucoup en Python.
Boucleswhile
sur une ligne
Comme avec une instructionif
, une bouclewhile
peut être spécifiée sur une ligne. S'il y a plusieurs instructions dans le bloc qui composent le corps de la boucle, elles peuvent être séparées par des points-virgules (;
):
>>>
>>> n = 5
>>> while n > 0: n -= 1; print(n)
4
3
2
1
0
Cela ne fonctionne cependant qu'avec des instructions simples. Vous ne pouvez pas combiner deux instructions composées en une seule ligne. Ainsi, vous pouvez spécifier une bouclewhile
sur une seule ligne comme ci-dessus, et vous écrivez une instructionif
sur une ligne:
>>>
>>> if True: print('foo')
foo
Mais vous ne pouvez pas faire ça:
>>>
>>> while n > 0: n -= 1; if True: print('foo')
SyntaxError: invalid syntax
N'oubliez pas quePEP 8 décourage plusieurs instructions sur une ligne. Donc, vous ne devriez probablement pas faire tout cela très souvent de toute façon.
Conclusion
Dans ce didacticiel, vous avez découvertindefinite iteration à l'aide de la boucle Pythonwhile
. Vous pouvez désormais:
-
Construire des boucles
while
basiques et complexes -
Exécution de la boucle d'interruption avec
break
etcontinue
-
Utilisez la clause
else
avec une bouclewhile
-
Traitez les boucles infinies
Vous devriez maintenant avoir une bonne compréhension de la façon d'exécuter un morceau de code de manière répétitive.
__ Take the Quiz: Testez vos connaissances avec notre quiz interactif «Python» tout en «Boucles». À la fin, vous recevrez un score afin que vous puissiez suivre vos progrès d'apprentissage au fil du temps:
Le didacticiel suivant de cette série couvredefinite iteration avec des bouclesfor
- exécution récurrente où le nombre de répétitions est spécifié explicitement.