189 votes

Comment puis-je donner un sens à la clause `else` des boucles Python?

De nombreux programmeurs Python sont probablement pas au courant que la syntaxe de l' while boucles et for boucles comprend une option de else: clause de:

for val in iterable:
    do_something(val)
else:
    clean_up()

Le corps de l' else clause est une bonne place pour certains types de nettoyage des actions, et est exécuté sur l'arrêt normal de la boucle: I. e., la sortie de la boucle avec return ou break ignore l' else clause; quitter après un continue l'exécute. Je sais ce que parce que j'ai juste regardé (encore une fois), parce que je ne me souviens jamais lorsque l' else clause est exécutée.

Toujours? Sur "l'échec" de la boucle, comme le nom le suggère? Régulière de la résiliation? Même si la boucle est sortie avec return? Je ne pouvez jamais être certain que sans le regarder.

Je blâme mon persistance de l'incertitude sur le choix de mots-clés: - je trouver de l' else incroyablement unmnemonic pour cette sémantique. Ma question n'est pas "pourquoi est-ce le mot-clé utilisé à cette fin" (ce qui je ne serais probablement voter pour le fermer, mais seulement après avoir lu les réponses et les commentaires), mais comment puis-je penser à l' else mot-clé, de sorte que sa sémantique logique, et je peut donc s'en souvenir?

Je suis sûr qu'il y a une bonne quantité de discussion à ce sujet, et je peux imaginer que le choix a été fait pour des raisons de cohérence avec l' try de l'énoncé else: de l'alinéa (que j'ai aussi de regarder en haut), et avec l'objectif de ne pas ajouter à la liste de Python mots réservés. Peut-être les raisons pour le choix d' else permettra de clarifier sa fonction et de le rendre plus mémorable, mais je suis après le raccordement du nom de la fonction, non pas après une explication historique en soi.

Les réponses à cette question, ma question a été brièvement fermé comme un doublon, contiennent beaucoup d'histoire. Ma question a un accent différent (comment connecter la une sémantique spécifique de l' else avec le mot-clé le choix), mais je pense qu'il devrait y avoir un lien à cette question quelque part.

214voto

drawoc Points 1501

(Ce qui est inspirée par @Mark Tolonen de la réponse.)

Un if instruction s'exécute ses else clause si sa condition est false. De manière identique, un while boucle s'exécute la clause else si sa condition est false.

Cette règle correspond au comportement que vous avez décrit:

  • En exécution normale, tandis que la boucle s'exécute tant que la condition est false, et donc naturellement la sortie de la boucle s'exécute la clause else.
  • Lorsque vous exécutez une break déclaration, vous sortir de la boucle sans évaluation de la condition, de sorte que la condition ne peut pas évaluer de faux et vous ne faites jamais fonctionner la clause else.
  • Lorsque vous exécutez une continue déclaration, vous l'évaluation de l'état de nouveau, et faire exactement ce que vous le feriez normalement au début d'une itération de boucle. Donc, si la condition est vraie, vous gardez en boucle, mais si il est faux d'exécuter la clause else.
  • D'autres méthodes de sortir de la boucle, comme return, ne permettent pas d'évaluer l'état et, par conséquent, de ne pas exécuter la clause else.

for boucles se comportent de la même manière. Il suffit de considérer l'état comme vrai si l'itérateur a plus d'éléments, ou false sinon.

36voto

Moses Koledoye Points 60613

Mieux de penser à elle de cette façon: L' else bloc de toujours être exécutée si tout va droit dans le précédent for bloc à ce qu'elle arrive à épuisement.

Droit dans ce contexte, personne ne exception, n break, n return. Toute déclaration qui détourne le contrôle de for sera la cause de la else bloc pour être contourné.


Une utilisation courante de cas est trouvé lors de la recherche d'un élément dans un iterable, pour qui la recherche est soit appelé à l'arrêt lorsque l'élément est trouvé ou un "not found" drapeau est hissé/imprimé par la suite else bloc:

for items in basket:
    if isinstance(item, Egg):
        break
else:
    print("No eggs in basket")  

Un continue ne pas détourner le contrôle de for, de sorte que le contrôle de procéder à l' else après l' for est épuisé.

32voto

Mark Tolonen Points 32702

Quand un if d'exécuter une else? Lors de sa condition est fausse. C'est exactement le même pour l' while/else. Ainsi, vous pouvez penser de while/else d' if qui maintient l'exécution de sa véritable condition, jusqu'à ce qu'elle renvoie la valeur faux. Un break ne change pas. Il saute de l'contenant boucle avec aucune évaluation. L' else est exécuté seulement si l'évaluation de l' if/while condition est fausse.

L' for est similaire, à l'exception de ses fausses condition est épuisant son itérateur.

continue et break ne pas exécuter else. Ce n'est pas leur fonction. L' break quitte le contenant de la boucle. L' continue remonte vers le haut de la boucle, où la condition de la boucle est évaluée. C'est l'acte de l'évaluation de l' if/while false (ou for n'a pas plus d'éléments) qui s'exécute else et pas d'autre moyen.

24voto

Alex Hall Points 20790

C'est ce qu'il signifie essentiellement:

for/while ...:
    if ...:
        break
if there was a break:
    pass
else:
    ...

C'est une jolie manière de l'écriture de ce modèle commun:

found = False
for/while ...:
    if ...:
        found = True
        break
if not found:
    ...

L' else clause ne sera pas exécutée si il y a un return car return feuilles de la fonction, comme il le devrait. La seule exception à ce qui vous pouvez peut-être penser à est - finally, dont le but est d'être sûr que c'est toujours exécuté.

continue n'a rien de spécial à voir avec cette affaire. Il provoque l'itération courante de la boucle à la fin de ce qui peut se produire à la fin de la totalité de la boucle, et clairement, dans ce cas, la boucle n'était pas terminé par un break.

try/else est similaire:

try:
    ...
except:
    ...
if there was an exception:
    pass
else:
    ...

20voto

Keiwan Points 5344

Si vous pensez à votre boucle comme une structure similaire à ceci (un peu de pseudo-code):

loop:
if condition then

   ... //execute body
   goto loop
else
   ...

il pourrait faire un peu plus de sens. Une boucle est essentiellement juste un if déclaration qui est répété jusqu'à ce que la condition est false. Et c'est le point important. La boucle vérifie son état et voit que c'est false, donc exécute l' else (comme pour une normale if/else), puis la boucle est terminée.

Donc d'avis que l' else seulement est exécutée lorsque la condition est vérifiée. Cela signifie que si vous quittez le corps de la boucle dans le milieu de l'exécution avec par exemple un return ou break, puisque la condition n'est pas vérifié à nouveau, l' else cas ne sera pas exécutée.

Un continue sur l'autre main, elle arrête l'exécution, puis saute en arrière pour vérifier l'état de la boucle de nouveau, c'est pourquoi l' else peut être atteint dans ce scénario.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X