Boucles Python "while" (Itération indéfinie)

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 bouclewhile, 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 et3 est imprimé.

  • Cela continue jusqu'à ce quen 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 Pythonbreak 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 Pythoncontinue 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.

thought balloon

À 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 boucleswhile basiques et complexes

  • Exécution de la boucle d'interruption avecbreak etcontinue

  • Utilisez la clauseelse 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.