web-dev-qa-db-fra.com

Clause Else sur l'instruction Python while

J'ai remarqué que le code suivant est légal en Python. Ma question est pourquoi? Y a-t-il une raison spécifique?

n = 5
while n != 0:
    print n
    n -= 1
else:
    print "what the..."
279
Ivan

La clause else n'est exécutée que lorsque votre condition while devient fausse. Si vous break sortez de la boucle ou si une exception est levée, elle ne sera pas exécutée.

Une façon de penser est comme une construction if/else par rapport à la condition:

if condition:
    handle_true()
else:
    handle_false()

est analogue à la construction en boucle:

while condition:
    handle_true()
else:
    # condition is false now, handle and go on with the rest of the program
    handle_false()

Un exemple pourrait être dans les lignes de:

while value < threshold:
    if not process_acceptable_value(value):
        # something went wrong, exit the loop; don't pass go, don't collect 200
        break
    value = update(value)
else:
    # value >= threshold; pass go, collect 200
    handle_threshold_reached()
342
ars

La clause else est exécutée si vous quittez un bloc normalement, en activant la condition de boucle ou en tombant au bas d'un bloc try. Il est pas exécuté si vous break ou return sur un bloc, ou si vous déclenchez une exception. Cela fonctionne non seulement pour les boucles while et for, mais aussi pour les blocs.

Vous le trouverez généralement à des endroits où vous quitteriez normalement une boucle tôt, et courir à la fin de la boucle est une occasion inattendue/inhabituelle. Par exemple, si vous parcourez une liste en cherchant une valeur:

for value in values:
    if value == 5:
        print "Found it!"
        break
else:
    print "Nowhere to be found. :-("
87
John Kugelman

En réponse à Is there a specific reason?, voici une application intéressante: sortir de plusieurs niveaux de boucle.

Voici comment cela fonctionne: la boucle externe est interrompue à la fin et ne sera exécutée qu’une fois. Toutefois, si la boucle interne se termine (ne trouve aucun diviseur), elle atteint alors l'instruction else et la rupture externe n'est jamais atteinte. De cette façon, une coupure dans la boucle interne se séparera des deux boucles plutôt que d'une seule.

for k in [2, 3, 5, 7, 11, 13, 17, 25]:
    for m in range(2, 10):
        if k == m:
            continue
        print 'trying %s %% %s' % (k, m)
        if k % m == 0:
            print 'found a divisor: %d %% %d; breaking out of loop' % (k, m)
            break
    else:
        continue
    print 'breaking another level of loop'
    break
else:
    print 'no divisor could be found!'

Pour les deux boucles while et for, l'instruction else est exécutée à la fin, à moins que break ne soit utilisé.

Dans la plupart des cas, il existe de meilleures façons de le faire (en l’enveloppant dans une fonction ou en levant une exception), mais cela fonctionne!

39
Mark

La clause else est exécutée lorsque la condition while est évaluée à false.

De la documentation :

L'instruction while est utilisée pour une exécution répétée tant qu'une expression est vraie:

while_stmt ::=  "while" expression ":" suite
                ["else" ":" suite]

Ceci teste à plusieurs reprises l'expression et, s'il est vrai, exécute la première suite; si l'expression est false (ce peut être la première fois qu'elle est testée), la suite de la clause else, si elle est présente, est exécutée et la boucle se termine.

Une instruction break exécutée dans la première suite met fin à la boucle sans exécuter la suite de la clause else. Une instruction continue exécutée dans la première suite ignore le reste de la suite et recommence à tester l'expression.

18
Mark Rushakoff

Ma réponse portera sur QUAND nous pouvons utiliser tant que/pour d’autre.

Au premier abord, il semble qu’il n’y ait pas de différence lorsqu’on utilise

while CONDITION:
    EXPRESSIONS
print 'ELSE'
print 'The next statement'

et

while CONDITION:
    EXPRESSIONS
else:
    print 'ELSE'
print 'The next statement'

Parce que l'instruction print 'ELSE' semble toujours exécutée dans les deux cas (à la fois lorsque la boucle while est terminée ou non exécutée).

Alors, c'est différent uniquement lorsque l'instruction print 'ELSE' ne sera pas exécutée. C'est lorsqu'il y aura un break à l'intérieur du bloc de code sous while

In [17]: i = 0

In [18]: while i < 5:
    print i
    if i == 2:
        break
    i = i +1
else:
    print 'ELSE'
print 'The next statement'
   ....:
0
1
2
The next statement

Si diffère de:

In [19]: i = 0

In [20]: while i < 5:
    print i
    if i == 2:
        break
    i = i +1
print 'ELSE'
print 'The next statement'
   ....:
0
1
2
ELSE
The next statement

return ne fait pas partie de cette catégorie, car il a le même effet dans les deux cas précédents.

exception levée ne cause pas non plus de différence, car lorsqu’il est levé, le code suivant sera exécuté dans le gestionnaire d’exceptions (sauf block), le code dans la clause else ou juste après la clause while ne le sera pas. être exécuté.

14
HVNSweeting

C'est utile pour les interactions sociales.

while (Date != "January 1st"):
    time.sleep(1)
else:
    print("Happy new year!")
0
Guimoute

Je sais que c'est une vieille question mais ...

Comme l'a dit Raymond Hettinger, il devrait s'appeler while/no_break au lieu de while/else.
Je trouve qu'il est facile à comprendre et à regarder cet extrait.

n = 5
while n > 0:
    print n
    n -= 1
    if n == 2:
        break
if n == 0:
    print n

Maintenant, au lieu de vérifier la condition après la boucle while, nous pouvons l'échanger avec else et supprimer ce contrôle.

n = 5
while n > 0:
    print n
    n -= 1
    if n == 2:
        break
else:  # read it as "no_break"
    print n

Je le lis toujours comme while/no_break pour comprendre le code et cette syntaxe est beaucoup plus logique.

0
Iluvatar

Else est exécuté si la boucle while ne s'est pas cassée.

J'aime bien y penser avec une métaphore du "coureur".

Le "else" revient à franchir la ligne d'arrivée, que vous ayez commencé au début ou à la fin de la piste. "else" est seulement pas exécuté si vous cassez quelque part entre les deux.

runner_at = 0 # or 10 makes no difference, if unlucky_sector is not 0-10
unlucky_sector = 6
while runner_at < 10:
    print("Runner at: ", runner_at)
    if runner_at == unlucky_sector:
        print("Runner fell and broke his foot. Will not reach finish.")
        break
    runner_at += 1
else:
    print("Runner has finished the race!") # Not executed if runner broke his foot.

Les principaux cas d'utilisation utilisent cette rupture de boucles imbriquées ou si vous souhaitez exécuter certaines instructions uniquement si la boucle ne s'est pas cassée quelque part (pensez que la rupture est une situation inhabituelle).

Par exemple, voici un mécanisme permettant de sortir d'une boucle interne sans utiliser de variables ni try/catch:

for i in [1,2,3]:
    for j in ['a', 'unlucky', 'c']:
        print(i, j)
        if j == 'unlucky':
            break
    else: 
        continue  # Only executed if inner loop didn't break.
    break         # This is only reached if inner loop 'breaked' out since continue didn't run. 

print("Finished")
# 1 a
# 1 b
# Finished
0
Leo Ufimtsev

L'instruction else: est exécutée uniquement lorsque la boucle while ne remplit plus sa condition (dans votre exemple, lorsque n != 0 est faux).

Donc, le résultat serait ceci:

5
4
3
2
1
what the...
0
BoltClock