2009-11-02 16 views
95

Mögliche Duplizieren:
Emulate a do-while loop in Python?Gibt es ein "do ... bis" in Python?

Gibt es eine

do until x: 
    ... 

in Python oder eine nette Weise, eine solche Looping konstruieren zu implementieren?

+8

Wenn Sie im Handbuch zur Sprachreferenz nachgesehen haben, welche zusammengesetzten Aussagen haben Sie gesehen? http://docs.python.org/reference/compound_stmts.html –

+0

Duplizieren: http://stackoverflow.com/questions/743164/do-while-loop-in-python – ChristopheD

+3

Ein Do-While (obwohl es aufgerufen werden sollte 'bis') ist mein größter Wunsch für Python. –

Antwort

181

There is no do-while loop in Python.

Dies ist ein ähnliches Konstrukt, von der Verbindung oben genommen.

while True: 
    do_something() 
    if condition(): 
     break 
+25

BTW, das heißt "Loop-and-a-half".Python unterstützt dieses Konstrukt weiterhin, weil es eines der am einfachsten zu schreibenden und zu verstehenden Schleifenmuster ist. Siehe http://www.cs.duke.edu/~ola/patterns/plopd/loops.html#loop-and-a-half – Brandon

+1

@Brandon Ist das anders als: 'while! Condition do_something()'? – Bort

+6

@Bort Das Schleifen-and-a-half-Konstrukt garantiert, dass 'do_something()' mindestens einmal ausgeführt wird, auch wenn 'condition()' zu Beginn der Schleife wahr ist. Ihr 'while not condition(): do_something()' -Konstrukt wird 'do_something()' niemals ausführen, wenn 'condition()' am Anfang als wahr ausgewertet wird. – Brandon

22

gibt es keine vorverpackten "do-while", aber die allgemeine Python Weise eigentümlich looping Konstrukte zu implementieren ist durch Generatoren und andere Iteratoren, zB:

import itertools 

def dowhile(predicate): 
    it = itertools.repeat(None) 
    for _ in it: 
    yield 
    if not predicate(): break 

so zum Beispiel:

i=7; j=3 
for _ in dowhile(lambda: i<j): 
    print i, j 
    i+=1; j-=1 

führt ein Bein, wie gewünscht, obwohl das Prädikat bereits am Anfang falsch ist.

Normalerweise ist es besser, mehr von der Schleifenlogik in Ihren Generator (oder einen anderen Iterator) zu kapseln. Wenn Sie beispielsweise häufig Fälle haben, in denen eine Variable zunimmt, wird eine kleiner und Sie müssen eine do/while-Schleife vergleichen könnten Sie den Code ein:

for i, j in incandec(i=7, j=3): 
    print i, j 

Es liegt an Ihnen, wie viel Schleife bezogene Logik, die Sie in Ihrem Generator setzen wollen (oder andere Iterator) und wie viel:

def incandec(i, j, delta=1): 
    while True: 
    yield i, j 
    if j <= i: break 
    i+=delta; j-=delta 

, die Sie mögen können Du willst es draussen haben (wie bei jedem anderen u se einer Funktion, Klasse oder eines anderen Mechanismus, den Sie verwenden können, um Code aus Ihrem Hauptstrom der Ausführung umzuwandeln), aber im Allgemeinen mag ich, dass der Generator in einer for Schleife verwendet wird, die wenig (idealerweise keine) "Schleife hat Steuerungslogik "(Code, der sich auf das Aktualisieren von Zustandsvariablen für den nächsten Schleifenabschnitt bezieht und/oder Tests durchführt, ob Sie erneut Schleifen ausführen sollten oder nicht).

+2

Sie könnten [itertools.takewhile] (https://docs.python.org/2/library/itertools.html#itertools.takewhile) verwenden. –

6

Nein, gibt es nicht. Stattdessen wird eine Verwendung while Schleifen wie:

while 1: 
...statements... 
    if cond: 
    break 
+6

Warum 'while 1'? Was ist los mit 'while True'? Warum erzwinge eine Konvertierung von int nach bool? –

+6

@ S.Lott, eigentlich, in Python 2.X, Wahr/Falsch sind keine Schlüsselwörter, sie sind nur in globalen Konstanten eingebaut (die wie jede andere Variable neu zugewiesen werden können), so dass der Interpreter überprüfen muss, worauf er hinweist. Siehe http://stackoverflow.com/a/3815387/311220 – Acorn

+5

"Der Interpreter muss überprüfen, worauf er hinweist"? Was? Sind Sie der Meinung, dass dies eine nützliche Optimierung ist? Falls ja, haben Sie "timeit" -Benchmarks, um diesen Anspruch zu begründen? –

17

Ich ziehe eine Schleifenvariable zu verwenden, da es ein bisschen schöner zu lesen neigt als nur „während 1:“ und nicht hässlich aussehenden break Aussage:

finished = False 
while not finished: 
    ... do something... 
    finished = evaluate_end_condition() 
Verwandte Themen