2009-11-02 4 views
95

Eventuali duplicati:
Emulate a do-while loop in Python?C'è un "do ... until" in Python?

Esiste un

do until x: 
    ... 

in Python, o un bel modo per attuare tale loop costrutto?

+8

Quando hai cercato nel manuale di riferimento del linguaggio, quali dichiarazioni composte hai visto? http://docs.python.org/reference/compound_stmts.html –

+0

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

+3

Un do-while (anche se dovrebbe essere chiamato 'until') è il mio più grande desiderio per Python. –

risposta

181

There is no do-while loop in Python.

Questo è un costrutto simile, preso dal link sopra.

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

BTW, questo è chiamato "loop-and-a-half".Python continua a supportare questo costrutto perché è uno dei pattern di loop più facili da scrivere e capire correttamente. Vedi http://www.cs.duke.edu/~ola/patterns/plopd/loops.html#loop-and-a-half – Brandon

+1

@Brandon È diverso da: 'while! Condition do_something()'? – Bort

+6

@Bort Il costrutto loop-and-a-half garantisce che 'do_something()' sarà eseguito almeno una volta, anche se 'condition()' è vero all'inizio del ciclo. Il costrutto 'while not condition(): do_something()' non eseguirà mai 'do_something()' se 'condition()' restituisce true all'inizio. – Brandon

22

Non c'è alcun preconfezionato "do-po", ma il modo Python generale per implementare costrutti di loop peculiari è attraverso generatori e altri iteratori, ad esempio:

import itertools 

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

così, ad esempio:

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

esegue una gamba, come desiderato, anche se il predicato è già falso all'inizio.

Normalmente è meglio incapsulare più logiche di loop nel generatore (o altro iteratore), ad esempio, se si hanno spesso casi in cui una variabile aumenta, una diminuisce e occorre un ciclo do/while per confrontarle , è possibile codificare:

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

che può essere utilizzato come:

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

sta a voi quanto la logica loop-correlate che si desidera mettere dentro il generatore (o altro iteratore) e quanto vuoi avere al di fuori di esso (proprio come per qualsiasi altro te se di una funzione, classe o altro meccanismo è possibile utilizzare per rifattorizzare il codice dal proprio flusso principale di esecuzione), ma, in generale, mi piace vedere il generatore utilizzato in un ciclo for che ha un piccolo ciclo (idealmente nessuno) logica di controllo "(codice relativo all'aggiornamento delle variabili di stato per il prossimo loop leg e/o all'esecuzione di test sul fatto che si debba ripetere il ciclo o meno).

+2

È possibile utilizzare [itertools.takewhile] (https://docs.python.org/2/library/itertools.html#itertools.takewhile). –

6

No, non c'è. Invece utilizzare un while ciclo come ad esempio:

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

Perché 'mentre 1'? Cosa c'è di sbagliato in 'while True'? Perché forzare una conversione da int a bool? –

+6

@ S.Lott, in realtà, in Python 2.X, True/False non sono parole chiave, sono solo costruite in costanti globali (che sono riassegnabili come qualsiasi altra variabile), quindi l'interprete deve controllare a cosa puntano. Vedi http://stackoverflow.com/a/3815387/311220 – Acorn

+5

"l'interprete deve controllare che cosa indicano"? Che cosa? Stai affermando che si tratta di una sorta di ottimizzazione utile? In tal caso, si dispone di parametri di riferimento temporali per dimostrare tale affermazione? –

17

Io preferisco usare una variabile loop, in quanto tende a leggere un po 'più bello di un semplice "mentre 1:", e non è un brutto aspetto break dichiarazione:

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