Pourquoi python utilise-t-il 'else' après les boucles for et while?

482

Je comprends comment cette construction fonctionne:

for i in range(10):
    print(i)

    if i == 9:
        print("Too big - I'm giving up!")
        break;
else:
    print("Completed successfully")

Mais je ne comprends pas pourquoi elseest utilisé comme mot-clé ici, car il suggère que le code en question ne s'exécute que si le forbloc ne se termine pas, ce qui est l'opposé de ce qu'il fait! Peu importe comment j'y pense, mon cerveau ne peut pas évoluer de manière transparente de la fordéclaration au elsebloc. Pour moi, continueou continuewithaurait plus de sens (et j'essaie de m'entraîner à le lire comme tel).

Je me demande comment les codeurs Python lisent cette construction dans leur tête (ou à haute voix, si vous le souhaitez). Peut-être que je manque quelque chose qui rendrait ces blocs de code plus facilement déchiffrables?

Kent Boogaart
la source
26
Vous voudrez peut-être le traduire par "alors" dans votre tête.
Marcin
63
N'oubliez pas la ligne clé du Zen of Python: "... cette façon peut ne pas être évidente au premier abord, sauf si vous êtes néerlandais."
Daniel Roseman
51
Dans ma tête, je le traduit par "sinon casser" . Et, comme il breakest beaucoup utilisé dans les boucles "je l'ai trouvé" , vous pouvez le traduire en "s'il n'est pas trouvé" , ce qui n'est pas loin de ce qui se elselit
MestreLion
29
Je pense que la vraie question que beaucoup de gens ont ici est "Quelle est la différence entre for ... else foo()et juste mettre foo()après la boucle for?" Et la réponse est qu'ils se comportent différemment uniquement si la boucle contient un break(comme décrit en détail ci-dessous).
Sam Kauffman
10
Un point-virgule en python ... mes yeux me font mal .. même si c'est syntaxiquement correct, ce n'est pas une bonne pratique de le faire
DarkCygnus

Réponses:

278

C'est une construction étrange, même pour les codeurs Python chevronnés. Lorsqu'il est utilisé en conjonction avec des boucles for, cela signifie essentiellement "trouver un élément dans l'itérable, sinon si aucun n'a été trouvé, faites ...". Un péché:

found_obj = None
for obj in objects:
    if obj.key == search_key:
        found_obj = obj
        break
else:
    print('No object found.')

Mais chaque fois que vous voyez cette construction, une meilleure alternative consiste à encapsuler la recherche dans une fonction:

def find_obj(search_key):
    for obj in objects:
        if obj.key == search_key:
            return obj

Ou utilisez une liste de compréhension:

matching_objs = [o for o in objects if o.key == search_key]
if matching_objs:
    print('Found {}'.format(matching_objs[0]))
else:
    print('No object found.')

Il n'est pas sémantiquement équivalent aux deux autres versions, mais fonctionne assez bien dans le code critique sans performances où il importe peu que vous itériez la liste entière ou non. D'autres peuvent être en désaccord, mais personnellement, j'éviterais d'utiliser les blocs for-else ou while-else dans le code de production.

Voir aussi [Python-ideas] Résumé des fils de discussion for ... else

Björn Lindqvist
la source
50
La compréhension de la liste n'est pas la bonne. Si vous recherchez un seul élément, comme dans les forexemples de boucle, et que vous souhaitez utiliser une expression de générateur / compréhension de liste, alors vous voulez next((o for o in objects if o.key == search_key), None)ou l'encapsuler dans un try/ exceptet n'utilisez aucune valeur par défaut au lieu d'un if/ else.
agf
4
et comme la réponse de Lance Helsten, il y a des cas réels où il vaut mieux utiliser une for/elseconstruction.
andrean
5
À votre santé. J'avais un dossier mal échancré où un elses'est apparié avec un foret je n'avais aucune idée que c'était légal.
maxywb
3
Je pense que la boucle for est la plus évidente des constructions là-bas.
Miles Rout
14
Il convient de mentionner que la clause else s'exécutera même si la boucle for a des valeurs, sauf si une breakinstruction est explicitement exécutée comme dans cet exemple. D'après les documents ci-dessus: "La elseclause a un autre problème perçu: s'il n'y en a pas breakdans la boucle, la elseclause est fonctionnellement redondante.". par exemplefor x in [1, 2, 3]:\n print x\n else:\n print 'this executes due to no break'
dhackner
587

Une construction courante consiste à exécuter une boucle jusqu'à ce que quelque chose soit trouvé, puis à sortir de la boucle. Le problème est que si je sors de la boucle ou si la boucle se termine, je dois déterminer quel cas s'est produit. Une méthode consiste à créer un indicateur ou une variable de stockage qui me permettra de faire un deuxième test pour voir comment la boucle a été quittée.

Par exemple, supposons que je dois rechercher dans une liste et traiter chaque élément jusqu'à ce qu'un élément indicateur soit trouvé, puis arrêter le traitement. Si l'élément indicateur est manquant, une exception doit être déclenchée.

En utilisant la construction Python for... elsevous avez

for i in mylist:
    if i == theflag:
        break
    process(i)
else:
    raise ValueError("List argument missing terminal flag.")

Comparez cela à une méthode qui n'utilise pas ce sucre syntaxique:

flagfound = False
for i in mylist:
    if i == theflag:
        flagfound = True
        break
    process(i)

if not flagfound:
    raise ValueError("List argument missing terminal flag.")

Dans le premier cas, le raiseest étroitement lié à la boucle for avec laquelle il fonctionne. Dans le second cas, la liaison n'est pas aussi solide et des erreurs peuvent être introduites lors de la maintenance.

Lance Helsten
la source
69
Cela explique mieux que la réponse choisie où l'auteur ne comprend pas vraiment ce qui est pour-le-reste!
erikbwork
17
Je dois dire que ce sucre syntaxique pourrait pourrir les dents de votre projet. Cela ne ferait pas un Python: the good partslivre.
Boatcoder
1
Pouvez-vous confirmer que dans votre exemple, process(i)cela se produit pour chaque élément myliststrictement avant theflag, et non pour theflaglui-même? Est-ce que c'était prévu?
bli
4
processs'exécutera sur chacun iqui existe dans la liste avant qu'il theflagsoit atteint, il ne sera pas exécuté sur les éléments de la liste après theflag, et il ne sera pas exécuté sur theflag.
Lance Helsten
1
l'instruction else est également exécutée si l'itérable ne contient aucun élément
Lost Crotchet
173

Il y a une excellente présentation de Raymond Hettinger, intitulée Transforming Code into Beautiful, Idiomatic Python , dans laquelle il aborde brièvement l'histoire de la for ... elseconstruction. La section pertinente est "Distinguer plusieurs points de sortie en boucles" à partir de 15h50 et se poursuivant pendant environ trois minutes. Voici les points forts:

  • La for ... elseconstruction a été conçue par Donald Knuth en remplacement de certains GOTOcas d'utilisation;
  • Réutiliser le elsemot - clé était logique parce que "c'est ce que Knuth a utilisé, et les gens savaient, à ce moment-là, que toutes les [ fordéclarations] avaient intégré un ifet en GOTOdessous, et ils s'attendaient à ce que le else";
  • Rétrospectivement, cela aurait dû être appelé "pas de pause" (ou peut-être "nobreak"), et alors ce ne serait pas déroutant. *

Donc, si la question est: "Pourquoi ne modifient-ils pas ce mot-clé?" alors Cat Plus Plus a probablement donné la réponse la plus précise - à ce stade, il serait trop destructeur pour le code existant pour être pratique. Mais si la question que vous vous posez vraiment est pourquoi a elseété réutilisée en premier lieu, eh bien, apparemment, cela semblait être une bonne idée à l'époque.

Personnellement, j'aime le compromis de commenter # no breaken ligne partout où le elsepourrait être confondu, en un coup d'œil, comme appartenant à l'intérieur de la boucle. C'est assez clair et concis. Cette option est brièvement mentionnée dans le résumé que Bjorn a lié à la fin de sa réponse:

Pour être complet, je dois mentionner qu'avec un léger changement de syntaxe, les programmeurs qui veulent cette syntaxe peuvent l'avoir en ce moment:

for item in sequence:
    process(item)
else:  # no break
    suite

* Citation supplémentaire de cette partie de la vidéo: "Tout comme si nous appelions lambda makefunction, personne ne demanderait:" Que fait lambda? ""

Air
la source
33

Parce qu'ils ne voulaient pas introduire un nouveau mot-clé dans la langue. Chacun vole un identifiant et cause des problèmes de compatibilité descendante, c'est donc généralement un dernier recours.

Cat Plus Plus
la source
2
Il semble que finallycela aurait été un meilleur choix dans ce cas. Le mot clé finally n'était-il pas encore présent au moment de l'introduction de cette construction?
Ponkadoodle
26
@Wallacoloo finallyn'est pas beaucoup mieux, car cela implique que le bloc sera toujours exécuté après la boucle, et ce n'est pas le cas (car ce serait redondant en mettant simplement le code à exécuter après la boucle).
Cat Plus Plus
Cela ne peut pas non plus être finallydû au fait que la clause else est exécutée également lorsqu'elle continueest utilisée dans la boucle for - c'est-à-dire plusieurs fois et pas seulement à la fin.
2014
6
L' elseexécution de la clause @pepr n'est pas affectée par continue( documents et code de test )
Air
@AirThomas: +1. Tu as raison. Le elsen'est exécuté que lorsque le continueétait celui de la dernière itération.
pepr
33

Pour faire simple, vous pouvez penser à cela comme ça;

  • S'il rencontre la breakcommande dans la forboucle, la elsepièce ne sera pas appelée.
  • S'il ne rencontre pas la breakcommande dans la forboucle, la elsepièce sera appelée.

En d'autres termes, si pour l'itération de boucle n'est pas "rompue" avec break, la elsepartie sera appelée.

À l'infini
la source
Le elsebloc ne sera également pas exécuté si le corps de la boucle lève une exception.
Amal K
17

Le moyen le plus simple que j'ai trouvé pour `` obtenir '' ce que le for / else a fait, et plus important encore, quand l'utiliser, était de se concentrer sur l'endroit où l'instruction break saute. La construction For / else est un seul bloc. La coupure saute hors du bloc, et saute ainsi par dessus la clause else. Si le contenu de la clause else suivait simplement la clause for, il ne serait jamais sauté, et donc la logique équivalente devrait être fournie en la mettant dans un if. Cela a déjà été dit, mais pas tout à fait dans ces mots, donc cela peut aider quelqu'un d'autre. Essayez d'exécuter le fragment de code suivant. Je suis de tout coeur en faveur du commentaire "no break" pour plus de clarté.

for a in range(3):
    print(a)
    if a==4: # change value to force break or not
        break
else: #no break  +10 for whoever thought of this decoration
    print('for completed OK')

print('statement after for loop')
Neil_UK
la source
"Le saut saute hors du bloc, et saute donc" par-dessus "la clause else" - bien que cela puisse être utile comme moyen de "récupérer" for:/ else:, il ne fournit pas vraiment de justification pour le mot-clé else. Compte tenu du cadrage donné ici, il then:semble que ce serait beaucoup plus naturel. (Il y a des raisons d' elseêtre choisies, données dans d'autres réponses - elles ne sont tout simplement pas fournies ici.)
Mark Amery
16

Je pense que la documentation a une grande explication d' autre , continuez

[...] il est exécuté lorsque la boucle se termine par épuisement de la liste (avec pour) ou lorsque la condition devient fausse (avec while), mais pas lorsque la boucle se termine par une instruction break. "

Source: Python 2 docs: Tutoriel sur le flux de contrôle

Ayan
la source
13

Je l'ai lu quelque chose comme:

Si vous êtes toujours dans les conditions pour exécuter la boucle, faites des choses, sinon faites autre chose.

pcalcao
la source
Votre encore sur les conditions est utile (+1) bien que ce soit faux - c'est humain ;-)
Wolf
-1; cette prononciation de for:/ else:donne l'impression que le else:sera toujours exécuté après la boucle, ce qui n'est pas le cas.
Mark Amery
11

Depuis la partie technique a été à peu près répondu, mon commentaire est juste en relation avec la confusion qui produit ce mot-clé recyclé .

Étant Python un langage de programmation très éloquent , l'utilisation abusive d'un mot-clé est plus notoire. Le elsemot-clé décrit parfaitement une partie du flux d'un arbre de décision, "si vous ne pouvez pas faire ceci, (sinon) faites cela". C'est implicite dans notre propre langue.

Au lieu de cela, l'utilisation de ce mot clé avec les instructions whileet forcrée de la confusion. La raison, notre carrière en tant que programmeurs nous a appris que la elsedéclaration réside dans un arbre de décision; sa portée logique , un wrapper qui renvoie conditionnellement un chemin à suivre. Pendant ce temps, les instructions de boucle ont un objectif explicite figuratif pour atteindre quelque chose. L'objectif est atteint après des itérations continues d'un processus.

if / else indiquer un chemin à suivre . Les boucles suivent un chemin jusqu'à ce que le «but» soit terminé .

Le problème est que elsec'est un mot qui définit clairement la dernière option d'une condition. La sémantique du mot est partagée par Python et Human Language. Mais le mot else en langage humain n'est jamais utilisé pour indiquer les actions qu'une personne ou quelque chose entreprendra après que quelque chose soit terminé. Il sera utilisé si, dans le processus de le terminer, un problème survient (plus comme une déclaration de rupture ).

À la fin, le mot-clé restera en Python. Il est clair que c'était une erreur, plus clair quand chaque programmeur essaie de trouver une histoire pour comprendre son utilisation comme un appareil mnémotechnique. J'aurais adoré s'ils choisissaient plutôt le mot-clé then. Je crois que ce mot-clé s'intègre parfaitement dans ce flux itératif, le gain après la boucle.

Cela ressemble à cette situation que certains enfants ont après avoir suivi chaque étape de l'assemblage d'un jouet: Et PUIS quoi papa?

3rdWorldCitizen
la source
Je pense que cette réponse répond au problème de confusion dont je pense que le PO parlait. Le mot-clé else fait exactement le contraire de ce que vous attendez du sens anglais de else lorsqu'il est attaché à l'action de for. En théorie, le for ... else aurait pu fonctionner différemment en ce que vous vous retrouvez dans la partie else lorsque la boucle est rompue, mais le problème est que pour l'utiliser pour trouver l'élément x et gérer le cas où x est introuvable, vous devrez peut-être utiliser un drapeau ou un autre test après le tout pour .. else construct
Spacen Jasset
7

Je l'ai lu comme "Lorsque le iterableest complètement épuisé et que l'exécution est sur le point de passer à l'instruction suivante après avoir terminé le for, la clause else sera exécutée." Ainsi, lorsque l'itération est interrompue break, cela ne sera pas exécuté.

0xc0de
la source
6

Je suis d'accord, c'est plutôt un «elif pas [condition (s) soulevant la pause]».

Je sais que c'est un vieux fil, mais je regarde la même question en ce moment, et je ne suis pas sûr que quiconque ait saisi la réponse à cette question de la façon dont je la comprends.

Pour moi, il existe trois façons de "lire" les instructions elsein For... elseou While... else, qui sont toutes équivalentes, sont les suivantes:

  1. else == if the loop completes normally (without a break or error)
  2. else == if the loop does not encounter a break
  3. else == else not (condition raising break) (sans doute existe-t-il une telle condition, sinon vous n'auriez pas de boucle)

Donc, essentiellement, le "else" dans une boucle est vraiment un "elif ..." où '...' est (1) pas de rupture, ce qui équivaut à (2) PAS [condition (s) augmentant la rupture].

Je pense que la clé est que le elseest inutile sans la «pause», donc un for...elsecomprend:

for:
    do stuff
    conditional break # implied by else
else not break:
    do more stuff

Ainsi, les éléments essentiels d'une for...elseboucle sont les suivants, et vous les liriez en anglais plus simple:

for:
    do stuff
    condition:
        break
else: # read as "else not break" or "else not condition"
    do more stuff

Comme les autres affiches l'ont dit, une pause est généralement déclenchée lorsque vous êtes en mesure de localiser ce que recherche votre boucle, de sorte que else:devient "ce qu'il faut faire si l'élément cible n'est pas localisé".

Exemple

Vous pouvez également utiliser la gestion des exceptions, les interruptions et les boucles for ensemble.

for x in range(0,3):
    print("x: {}".format(x))
    if x == 2:
        try:
            raise AssertionError("ASSERTION ERROR: x is {}".format(x))
        except:
            print(AssertionError("ASSERTION ERROR: x is {}".format(x)))
            break
else:
    print("X loop complete without error")

Résultat

x: 0
x: 1
x: 2
ASSERTION ERROR: x is 2
----------
# loop not completed (hit break), so else didn't run

Exemple

Exemple simple avec coupure.

for y in range(0,3):
    print("y: {}".format(y))
    if y == 2: # will be executed
        print("BREAK: y is {}\n----------".format(y))
        break
else: # not executed because break is hit
    print("y_loop completed without break----------\n")

Résultat

y: 0
y: 1
y: 2
BREAK: y is 2
----------
# loop not completed (hit break), so else didn't run

Exemple

Exemple simple où il n'y a aucune interruption, aucune condition provoquant une interruption et aucune erreur n'est rencontrée.

for z in range(0,3):
     print("z: {}".format(z))
     if z == 4: # will not be executed
         print("BREAK: z is {}\n".format(y))
         break
     if z == 4: # will not be executed
         raise AssertionError("ASSERTION ERROR: x is {}".format(x))
else:
     print("z_loop complete without break or error\n----------\n")

Résultat

z: 0
z: 1
z: 2
z_loop complete without break or error
----------
NotAnAmbiTurner
la source
6

Le elsemot-clé peut être déroutant ici, et comme beaucoup de gens l'ont souligné, quelque chose comme nobreak, notbreakest plus approprié.

Afin de comprendre for ... else ...logiquement, comparez-le avec try...except...else, non if...else..., la plupart des programmeurs python connaissent le code suivant:

try:
    do_something()
except:
    print("Error happened.") # The try block threw an exception
else:
    print("Everything is find.") # The try block does things just find.

De même, pensez breakà un type spécial de Exception:

for x in iterable:
    do_something(x)
except break:
    pass # Implied by Python's loop semantics
else:
    print('no break encountered')  # No break statement was encountered

La différence est pythonimplicite except breaket vous ne pouvez pas l'écrire, cela devient donc:

for x in iterable:
    do_something(x)
else:
    print('no break encountered')  # No break statement was encountered

Oui, je sais que cette comparaison peut être difficile et fastidieuse, mais elle clarifie la confusion.

cizixs
la source
Vous devez créer un lien vers la ressource lorsque vous copiez à partir de celle-ci: les notes Python de Nick Coghlan .
godaygo
@godaygo merci pour le lien. J'ai lu et accepté le concept lors de mon premier apprentissage de python, je n'ai pas mémorisé la source lors de l'écriture de la réponse.
cizixs
@cizixs Vous "n'avez pas mémorisé la source" mais vous vous êtes avéré juste inclure des phrases entières de commentaires identiques à l'original? Ooookaaaay.
Mark Amery
5

Les codes dans le elsebloc d'instructions seront exécutés lorsque la forboucle n'a pas été rompue.

for x in xrange(1,5):
    if x == 5:
        print 'find 5'
        break
else:
    print 'can not find 5!'
#can not find 5!

À partir des documents: rompre et continuer les instructions, et sinon les clauses sur les boucles

Les instructions de boucle peuvent avoir une clause else; elle est exécutée lorsque la boucle se termine par épuisement de la liste (avec for) ou lorsque la condition devient fausse (avec while), mais pas lorsque la boucle se termine par une instruction break. Ceci est illustré par la boucle suivante, qui recherche des nombres premiers:

>>> for n in range(2, 10):
...     for x in range(2, n):
...         if n % x == 0:
...             print(n, 'equals', x, '*', n//x)
...             break
...     else:
...         # loop fell through without finding a factor
...         print(n, 'is a prime number')
...
2 is a prime number
3 is a prime number
4 equals 2 * 2
5 is a prime number
6 equals 2 * 3
7 is a prime number
8 equals 2 * 4
9 equals 3 * 3

(Oui, c'est le bon code. Regardez attentivement: la clause else appartient à la boucle for, pas à l'instruction if.)

Lorsqu'elle est utilisée avec une boucle, la clause else a plus en commun avec la clause else d'une instruction try que celle des instructions if: la clause else d'une instruction try s'exécute lorsqu'aucune exception ne se produit et la clause else d'une boucle s'exécute lorsqu'aucune interruption ne se produit . Pour plus d'informations sur l'instruction try et les exceptions, voir Gestion des exceptions.

L'instruction continue, également empruntée à C, se poursuit avec la prochaine itération de la boucle:

>>> for num in range(2, 10):
...     if num % 2 == 0:
...         print("Found an even number", num)
...         continue
...     print("Found a number", num)
Found an even number 2
Found a number 3
Found an even number 4
Found a number 5
Found an even number 6
Found a number 7
Found an even number 8
Found a number 9
GoingMyWay
la source
1
Cela n'ajoute rien et ne répond pas à la question, qui n'est pas comment mais pourquoi .
Air
5

Voici une façon d'y penser que je n'ai vu personne mentionner ci-dessus:

Tout d'abord, rappelez-vous que les boucles for ne sont fondamentalement que du sucre syntaxique autour des boucles while. Par exemple, la boucle

for item in sequence:
    do_something(item)

peut être réécrit (environ) comme

item = None
while sequence.hasnext():
    item = sequence.next()
    do_something(item)

Deuxièmement, rappelez-vous que les boucles while sont essentiellement des blocs if simplement répétés! Vous pouvez toujours lire une boucle while comme "si cette condition est vraie, exécutez le corps, puis revenez et vérifiez à nouveau".

Donc, tandis que / else est parfaitement logique: c'est exactement la même structure que si / else, avec la fonctionnalité supplémentaire de bouclage jusqu'à ce que la condition devienne fausse au lieu de simplement vérifier la condition une fois.

Et puis, for / else est également parfaitement logique: parce que toutes les boucles for ne sont que du sucre syntaxique au-dessus des boucles while, il vous suffit de comprendre ce qu'est le conditionnel implicite de la boucle while sous-jacente, puis le reste correspond à quand cela condition devient Faux.

Aaron Gable
la source
4

Les bonnes réponses sont:

  • ce qui explique l'histoire, et
  • cela donne la bonne citation pour faciliter votre traduction / compréhension.

Ma note ici vient de ce que Donald Knuth a dit un jour (désolé, je ne trouve pas de référence) qu'il existe une construction où while-else est indiscernable de if-else, à savoir (en Python):

x = 2
while x > 3:
    print("foo")
    break
else:
    print("boo")

a le même flux (hors faibles différences de niveau) que:

x = 2
if x > 3:
    print("foo")
else:
    print("boo")

Le fait est que if-else peut être considéré comme du sucre syntaxique pour while-else qui a implicite breakà la fin de son ifbloc. L'implication opposée, à laquelle cette whileboucle est l'extension if, est plus courante (il s'agit simplement d'une vérification conditionnelle répétée / en boucle), car elle ifest souvent enseignée auparavant while. Cependant, ce n'est pas vrai car cela signifierait un elseblocage dans while-else serait exécuté à chaque fois que la condition est fausse.

Pour faciliter votre compréhension, pensez-y de cette façon:

Sans break, returnetc., les extrémités de la boucle que lorsque la condition n'est plus vrai et dans ce cas le elsebloc exécutent aussi une fois. Dans le cas de Python, forvous devez considérer les forboucles de style C (avec conditions) ou les traduire while.

Une autre note:

Une boucle intérieure prématurée break, returnetc. rend impossible la condition parce que l'exécution a sauté hors de la boucle alors que la condition était vraie et elle ne reviendrait jamais pour la vérifier à nouveau.

WloHu
la source
3

On pourrait y penser comme, elsecomme dans le reste des trucs, ou les autres trucs, qui n'ont pas été faits en boucle.

jamylak
la source
3
for i in range(3):
    print(i)

    if i == 2:
        print("Too big - I'm giving up!")
        break;
else:
    print("Completed successfully")

"else" ici est incroyablement simple, signifie simplement

1, "si for clauseest terminé"

for i in range(3):
    print(i)

    if i == 2:
        print("Too big - I'm giving up!")
        break;
if "for clause is completed":
    print("Completed successfully")

Il est difficile d'écrire des instructions aussi longues que "la clause for est terminée", donc ils introduisent "else".

else voici un si dans sa nature.

2, cependant, que diriez-vous for clause is not run at all

In [331]: for i in range(0):
     ...:     print(i)
     ...: 
     ...:     if i == 9:
     ...:         print("Too big - I'm giving up!")
     ...:         break
     ...: else:
     ...:     print("Completed successfully")
     ...:     
Completed successfully

Il est donc complètement énoncé est une combinaison logique:

if "for clause is completed" or "not run at all":
     do else stuff

ou dites-le de cette façon:

if "for clause is not partially run":
    do else stuff

ou de cette façon:

if "for clause not encounter a break":
    do else stuff
Calcul
la source
sinon agit comme une "transaction" dans SQL.
Calcul
2

Voici un autre cas d'utilisation idiomatique en plus de la recherche. Supposons que vous vouliez attendre qu'une condition soit vraie, par exemple un port à ouvrir sur un serveur distant, avec un certain délai d'expiration. Ensuite, vous pouvez utiliser une while...elseconstruction comme ceci:

import socket
import time

sock = socket.socket()
timeout = time.time() + 15
while time.time() < timeout:
    if sock.connect_ex(('127.0.0.1', 80)) is 0:
        print('Port is open now!')
        break
    print('Still waiting...')
else:
    raise TimeoutError()
Jonathan Sudiaman
la source
1

J'essayais juste de retrouver le sens moi-même. J'ai trouvé que ce qui suit aide!

• Considérez le elsecomme étant couplé avec l' ifintérieur de la boucle (au lieu de le for) - si la condition est remplie, rompez la boucle, sinon faites cela - sauf que c'est un elsecouplé avec plusieurs ifs!
• Si aucune ifréponse n'a été satisfaite, faites-le else.
• Les multiples ifs peuvent également être considérés comme des if- elifs!

Germaine Goh
la source
-2

Je considère la structure comme pour (if) A else B, et pour (if) -else est un if-else spécial , grosso modo . Cela peut aider à comprendre autre chose .

A et B sont exécutés au plus une fois, ce qui est identique à la structure if-else.

for (if) peut être considéré comme un if spécial, qui effectue une boucle pour essayer de remplir la condition if. Une fois la condition if remplie, A et break ; Sinon , B.

Jie Zhang
la source
-2

Python utilise une boucle else for et while pour que si rien ne s'applique à la boucle, il se passe autre chose. Par exemple:

test = 3
while test == 4:
     print("Hello")
else:
     print("Hi")

La sortie serait «Salut» encore et encore (si j'ai raison).

Mrmongoose64
la source