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>.

28voto

Neil_UK Punkte 993

Der einfachste Weg, um zu verstehen, was das for/else-Konstrukt bewirkt, und, was noch wichtiger ist, wann es zu verwenden ist, besteht darin, sich darauf zu konzentrieren, wohin die break-Anweisung springt. Das For/else-Konstrukt ist ein einzelner Block. Die Unterbrechung springt aus dem Block heraus und überspringt somit die else-Klausel. Wenn der Inhalt der else-Klausel einfach auf die for-Klausel folgen würde, würde sie niemals übersprungen werden, so dass die entsprechende Logik durch Einfügen in ein if bereitgestellt werden müsste. Dies wurde schon einmal gesagt, aber nicht mit diesen Worten, so dass es vielleicht jemand anderem hilft. Versuchen Sie, das folgende Codefragment auszuführen. Ich bin von ganzem Herzen für den "no break"-Kommentar aus Gründen der Klarheit.

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

EDIT - Ich stelle fest, dass diese Frage immer noch aktuell ist

Zweite bessere Gedanken ...

Die Bemerkung "keine Pause" ist ein negativer Aspekt. Es ist viel einfacher, eine positive Behauptung zu verstehen, und das ist, dass die for iterable erschöpft war.

for a in range(3):
    print(a)
    if a==4: # change value to force break or not
        print('ending for loop with a break')
        break
else: # for iterable exhausted  
    print('ending for loop as iterable exhausted')

print('for loop ended one way or another')

Das unterstreicht auch diese Interpretation

if iterable_supplies_a_value:
    run_the_for_with_that_value
else:
    do_something_else

23voto

Ayan Punkte 369

Ich denke, die Dokumentation bietet eine gute Erklärung für sonst , weiter

[...] Sie wird ausgeführt, wenn die Schleife durch Erschöpfung der Liste beendet wird (bei for) oder wenn die Bedingung falsch wird (bei while), aber nicht, wenn die Schleife durch eine break-Anweisung beendet wird."

Source : Python 2-Dokumente: Tutorial zum Kontrollfluss

19voto

3rdWorldCitizen Punkte 254

Da der technische Teil bereits weitgehend beantwortet wurde, bezieht sich mein Kommentar lediglich auf die Verwirrung die dies produzieren recycelt Stichwort.

Python ist ein sehr wortgewandt Programmiersprache ist die missbräuchliche Verwendung eines Schlüsselworts noch berüchtigter. Die else Das Schlüsselwort beschreibt perfekt einen Teil des Ablaufs eines Entscheidungsbaums: "Wenn du dies nicht tun kannst, dann tue (sonst) das". Es ist implizit in unserer eigenen Sprache.

Stattdessen wird dieses Schlüsselwort mit while y for Aussagen schafft Verwirrung. Der Grund: Unsere Karriere als Programmierer hat uns gelehrt, dass die else Anweisung befindet sich innerhalb eines Entscheidungsbaums; ihre logischer Anwendungsbereich ein Wrapper, der unter Vorbehalt einen zu verfolgenden Pfad zurückgeben. Schleifenanweisungen hingegen haben ein ausdrückliches Ziel, um etwas zu erreichen. Das Ziel wird nach kontinuierlichen Iterationen eines Prozesses erreicht.

if / else einen Weg angeben, dem man folgen kann . Schleifen einem Weg folgen, bis das "Ziel" erreicht ist .

Das Problem ist, dass else ist ein Wort, das die letzte Option in einer Bedingung eindeutig definiert. Die Semantik des Wortes sind beide gemeinsam genutzt von Python und der menschlichen Sprache. Das Wort else wird in der menschlichen Sprache jedoch nie verwendet, um die Handlungen anzuzeigen, die jemand oder etwas nach der Fertigstellung von etwas vornimmt. Es wird verwendet, wenn während der Fertigstellung ein Problem auftaucht (eher ein Pause Anweisung).

Am Ende bleibt das Schlüsselwort in Python. Es ist klar, dass es ein Fehler war, noch klarer wird es, wenn jeder Programmierer versucht, sich eine Geschichte auszudenken, um seine Verwendung wie eine Eselsbrücke zu verstehen. Ich hätte mich gefreut, wenn sie stattdessen das Schlüsselwort then . Ich glaube, dass dieses Schlüsselwort perfekt in diesen iterativen Fluss passt, den Auszahlung nach der Schleife.

Es ähnelt der Situation, die ein Kind hat, wenn es jeden Schritt beim Zusammenbau eines Spielzeugs befolgt hat: Und DANN was Papa?

15voto

WloHu Punkte 1207

Gute Antworten sind:

  • este die die Geschichte erklären, und
  • este gibt das Recht Zitat zur Erleichterung Ihrer Übersetzung/Verständnis.

Meine Anmerkung hier kommt von dem, was Donald Knuth einmal gesagt hat (leider kann ich die Referenz nicht finden), dass es ein Konstrukt gibt, bei dem while-else nicht von if-else zu unterscheiden ist, nämlich (in Python):

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

hat den gleichen Durchfluss (abgesehen von Unterschieden in der Höhe) wie:

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

Der Punkt ist, dass if-else als syntaktischer Zucker für while-else betrachtet werden kann, der implizite break am Ende seiner if Block. Die gegenteilige Implikation, dass while Schleife ist eine Erweiterung zu if ist häufiger anzutreffen (es handelt sich lediglich um eine wiederholte/geschleifte bedingte Prüfung), denn if wird oft vor der while . Das ist jedoch nicht wahr, denn das würde bedeuten else Block in while-else würde ausgeführt werden jedes Mal wenn die Bedingung falsch ist.

Um Ihnen das Verständnis zu erleichtern, stellen Sie sich das so vor:

Ohne break , return usw., die Schleife endet erst, wenn die Bedingung nicht mehr erfüllt ist, und in diesem Fall else Block wird ebenfalls einmal ausgeführt. Im Falle von Python for müssen Sie den C-Stil berücksichtigen for Schleifen (mit Bedingungen) oder übersetzen sie in while .

Eine weitere Anmerkung:

Vorzeitige break , return usw. innerhalb der Schleife macht es unmöglich, dass die Bedingung falsch wird, weil die Ausführung aus der Schleife herausspringt, während die Bedingung wahr ist, und sie würde nie zurückkommen, um sie erneut zu überprüfen.

14voto

pcalcao Punkte 15603

Ich habe es etwa so gelesen:

Wenn immer noch die Bedingungen für die Schleife erfüllt sind, tun Sie etwas, sonst etwas anderes tun.

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