757 Stimmen

Warum verwendet Python "else" nach for- und while-Schleifen?

Ich verstehe, wie dieses Konstrukt funktioniert:

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

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

Aber ich verstehe nicht, warum else wird hier als Schlüsselwort verwendet, da es nahelegt, dass der betreffende Code nur ausgeführt wird, wenn die for Block wird nicht abgeschlossen, was das Gegenteil von dem ist, was er tut! Egal, wie ich darüber denke, mein Gehirn kann nicht nahtlos von der for Anweisung an den else blockieren. Für mich, continue o continuewith wäre sinnvoller (und ich versuche, mich darauf einzustellen, es so zu lesen).

Ich frage mich, wie Python-Programmierer dieses Konstrukt in ihrem Kopf (oder laut, wenn Sie wollen) lesen. Vielleicht übersehe ich etwas, das solche Codeblöcke leichter entzifferbar machen würde?


Diese Frage bezieht sich auf die <em>zugrundeliegende Entwurfsentscheidung </em>d.h. <em>warum sie nützlich ist </em>um diesen Code schreiben zu können. Siehe auch <a href="https://stackoverflow.com/questions/3295938">Else-Klausel in der Python-Anweisung while </a>für die spezifische Frage nach <em>was die Syntax bedeutet </em>.

5voto

Aaron Gable Punkte 51

Hier ist eine Möglichkeit, darüber nachzudenken, die noch niemand erwähnt hat:

Zunächst sollten Sie bedenken, dass for-Schleifen im Grunde nur syntaktischer Zucker für while-Schleifen sind. Zum Beispiel, die Schleife

for item in sequence:
    do_something(item)

kann (ungefähr) umgeschrieben werden als

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

Zweitens: Denken Sie daran, dass while-Schleifen im Grunde nur wiederholte if-Blöcke sind! Sie können eine while-Schleife immer als "wenn diese Bedingung wahr ist, führe den Körper aus, komme dann zurück und prüfe erneut" lesen.

while/else macht also durchaus Sinn: Es ist genau dieselbe Struktur wie if/else, mit der zusätzlichen Funktionalität, eine Schleife zu durchlaufen, bis die Bedingung falsch wird, anstatt die Bedingung nur einmal zu überprüfen.

Und auch for/else macht durchaus Sinn: Da alle for-Schleifen nur syntaktischer Zucker auf while-Schleifen sind, muss man nur herausfinden, was die implizite Bedingung der zugrundeliegenden while-Schleife ist, und dann entspricht das else, wenn diese Bedingung falsch wird.

3voto

AbstProcDo Punkte 17041
for i in range(3):
    print(i)

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

"sonst" ist hier wahnsinnig einfach, einfach gemein

1, "wenn for clause ist abgeschlossen"

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")

Es ist mühsam, so lange Anweisungen wie "for-Klausel ist abgeschlossen" zu schreiben, also führen sie "else" ein.

else hier ist ein Wenn in seiner Natur.

2, Aber wie wäre es mit 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

Die vollständige Aussage ist also eine logische Kombination:

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

oder sagen wir es so:

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

oder auf diese Weise:

if "for clause not encounter a break":
    do else stuff

2voto

Jonathan Sudiaman Punkte 2324

Hier ist ein weiterer idiomatischer Anwendungsfall neben der Suche. Nehmen wir an, Sie möchten warten, bis eine Bedingung erfüllt ist, z. B. ein Port auf einem entfernten Server offen ist, und dazu eine Zeitüberschreitung. Dann könnten Sie eine while...else so konstruieren:

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()

2voto

Germaine Goh Punkte 21

Ich habe gerade wieder versucht, mir selbst einen Reim darauf zu machen. Ich habe festgestellt, dass das Folgende hilft!

- Denken Sie an die else als gepaart mit dem if innerhalb der Schleife (statt mit der for ) - wenn die Bedingung erfüllt ist, brechen Sie die Schleife ab, andernfalls tun Sie dies - außer es ist eine else gepaart mit mehreren if s!
- Wenn keine if s überhaupt befriedigt wurden, dann machen Sie die else .
- Die zahlreichen if s können auch tatsächlich als if - elif s!

2voto

Mhmoud Sabry Punkte 307

Die else-Klausel wird nach der normalen Beendigung der Schleife ausgeführt. Das bedeutet, dass die :==> else-Block direkt nach for/while wird nur ausgeführt, wenn die Schleife NICHT durch eine break-Anweisung beendet wird

for item in lista:
if(obj == item ):
    print("if True then break will run and else not run")
    break;
else:
print("in  else => obj not fount ")

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X