2009-11-02 13 views
95

Powiel możliwe:
Emulate a do-while loop in Python?Czy w języku Python występuje "do ... aż"?

Czy istnieje

do until x: 
    ... 

w Pythonie, czy to dobry sposób, aby realizować takie zapętlenie zbudować?

+8

Kiedy zapoznałeś się z instrukcją obsługi języka, jakie stwierdzenia złożone zostały wyświetlone? http://docs.python.org/reference/compound_stmts.html –

+0

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

+3

Do-while (chociaż powinno się to nazywać 'until') jest moim największym życzeniem dla Pythona. –

Odpowiedz

181

There is no do-while loop in Python.

To podobna konstrukcja, wykonane z łącza powyżej.

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

BTW, nazywa się to "pętla i pół".Python nadal wspiera tę konstrukcję, ponieważ jest to jeden z najłatwiejszych wzorów pętli do poprawnego pisania i rozumienia. Zobacz http://www.cs.duke.edu/~ola/patterns/plopd/loops.html#loop-and-a-half – Brandon

+1

@Bandon Czy różni się od: 'while while! Condition do_something()'? – Bort

+6

@Bort Konstrukcja typu "pętla i pół" gwarantuje, że 'do_something()' zostanie wykonane co najmniej raz, nawet jeśli 'condition()' jest prawdziwe na początku pętli. Wasza konstrukcja 'while not condition(): do_something()' nigdy nie wykona komendy 'do_something()' jeśli 'warunek()' zwróci wartość true na początku. – Brandon

22

nie ma paczkowane „Do-a”, ale ogólny sposób Pythona do wdrożenia specyficzne konstrukcje pętli jest przez generatory i inne iteratorów, np:

import itertools 

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

tak, na przykład:

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

wykonuje jedną nogę, zgodnie z oczekiwaniami, nawet jeśli predykat jest już fałszywy na początku.

Zazwyczaj lepiej hermetyzować więcej logiki pętli w generatorze (lub innym iteratorze) - na przykład, jeśli często występują przypadki, w których jedna zmienna wzrasta, jedna maleje, i trzeba porównać pętlę do/while , można kodować:

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

które można wykorzystać jak:

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

To do ciebie ile logika związane pętli chcesz umieścić wewnątrz generatora (lub innych iteracyjnej) i ile chcesz mieć na zewnątrz (tak jak w przypadku każdego innego użytkownika) se funkcji, klasy lub innego mechanizmu, którego możesz użyć do refaktoryzacji kodu z głównego strumienia wykonywania), ale ogólnie rzecz biorąc, lubię widzieć generator używany w pętli for, która ma małą (idealnie żadną) pętlę logika sterująca "(kod związany z aktualizowaniem zmiennych stanu dla następnej pętli i/lub testowaniem, czy powinieneś zapętlić się ponownie, czy nie).

+2

Można użyć [itertools.takewhile] (https://docs.python.org/2/library/itertools.html#itertools.takewhile). –

6

Nie, nie ma. Zamiast używać while pętli takich jak:

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

Dlaczego 'podczas 1?'? Co jest nie tak z 'while while True'? Po co wymuszać konwersję z int na bool? –

+6

@ S.Lott, faktycznie, w Pythonie 2.X, True/False nie są słowami kluczowymi, są one po prostu wbudowane w stałe globalne (które można przypisać jak każda inna zmienna), więc tłumacz musi sprawdzić, na co wskazują. Zobacz http://stackoverflow.com/a/3815387/311220 – Acorn

+5

"tłumacz musi sprawdzić, na co wskazują"? Co? Czy twierdzisz, że jest to jakaś użyteczna optymalizacja? Jeśli tak, to czy posiadasz testy porównawcze "timeit", aby uzasadnić to roszczenie? –

17

wolę używać zmiennej pętli, gdyż ma tendencję do czytania nieco ładniejszy niż tylko „natomiast 1”, a nie brzydkie wyglądające break stwierdzenie:

finished = False 
while not finished: 
    ... do something... 
    finished = evaluate_end_condition() 
Powiązane problemy