Muszę emulować pętlę „do-while” w programie Python. Niestety następujący prosty kod nie działa:
list_of_ints = [ 1, 2, 3 ]
iterator = list_of_ints.__iter__()
element = None
while True:
if element:
print element
try:
element = iterator.next()
except StopIteration:
break
print "done"
Zamiast „1,2,3, gotowe” wypisuje następujące dane wyjściowe:
[stdout:]1
[stdout:]2
[stdout:]3
None['Traceback (most recent call last):
', ' File "test_python.py", line 8, in <module>
s = i.next()
', 'StopIteration
']
Co mogę zrobić, aby złapać wyjątek „zatrzymaj iterację” i przerwać pętlę while?
Przykład, dlaczego taka rzecz może być potrzebna, pokazano poniżej jako pseudokod.
Maszyna stanowa:
s = ""
while True :
if state is STATE_CODE :
if "//" in s :
tokens.add( TOKEN_COMMENT, s.split( "//" )[1] )
state = STATE_COMMENT
else :
tokens.add( TOKEN_CODE, s )
if state is STATE_COMMENT :
if "//" in s :
tokens.append( TOKEN_COMMENT, s.split( "//" )[1] )
else
state = STATE_CODE
# Re-evaluate same line
continue
try :
s = i.next()
except StopIteration :
break
python
while-loop
do-while
grigoryvp
źródło
źródło
s=i.next()
raczej niż Brak i ewentualnie wykonujesz początkową pracę zamiast po prostu uczynić pierwsze przejście przez pętlę bezużytecznym.Odpowiedzi:
Nie jestem pewien, co próbujesz zrobić. Możesz zaimplementować następującą pętlę:
Lub:
Co robisz, próbując użyć pętli do while, aby wydrukować rzeczy z listy? Dlaczego nie po prostu użyć:
Aktualizacja:
Czy masz listę linii? I chcesz to powtarzać? Co powiesz na:
Czy to wydaje się być czymś zbliżonym do tego, czego byś chciał? W twoim przykładzie kodu byłoby to:
źródło
Oto bardzo prosty sposób emulacji pętli „do-while”:
Kluczowe cechy pętli „do-while” polegają na tym, że ciało pętli zawsze wykonuje się co najmniej raz, a warunek jest oceniany na dole ciała pętli. Przedstawiona tutaj struktura kontrolna realizuje oba z nich bez potrzeby wyjątków lub instrukcji break. Wprowadza jedną dodatkową zmienną logiczną.
źródło
break
. W szczególności, jeśli potrzebna jest logika POtest_loop_condition()
, która nie powinna zostać wykonana po zakończeniu, należy ją zapakowaćif condition:
. BTW,condition
jest niejasne. Bardziej opisowy:more
lubnotDone
.break
w pętlach i kiedy napotykam go w kodzie, który utrzymuję, stwierdzam, że pętla najczęściej mogłaby zostać napisana bez niego. Zaprezentowane rozwiązanie jest, według IMO, najczystszym sposobem reprezentowania konstrukcji do while w Pythonie.has_no_errors
lubend_reached
(w którym to przypadku uruchomi się pętlawhile not end_reached
Mój kod poniżej może być użyteczną implementacją, podkreślając główną różnicę między nimi robić vs podczas tak jak rozumiem.
Tak więc w tym przypadku zawsze przechodzisz przez pętlę przynajmniej raz.
źródło
while condition or first_pass:
. Następniecondition
jest zawsze oceniany jako pierwszy i ogólniefirst_pass
jest oceniany tylko dwukrotnie (pierwsza i ostatnia iteracja). Nie zapomnij zainicjowaćcondition
przed pętlą tego, co chcesz.Wyjątek spowoduje przerwanie pętli, więc równie dobrze możesz obsługiwać ją poza pętlą.
Myślę, że problem z twoim kodem polega na tym, że zachowanie
break
wewnątrzexcept
nie jest zdefiniowane. Zasadniczobreak
idzie tylko o jeden poziom wyżej, więc np.break
Wnętrzetry
idzie bezpośrednio dofinally
(jeśli istnieje) pozatry
, ale nie poza pętlę.Powiązane PEP: http://www.python.org/dev/peps/pep-3136
Podobne pytanie: Wyjście z zagnieżdżonych pętli
źródło
->
Możesz wykonać funkcję:
Ale 1) To brzydkie. 2) Warunek powinien być funkcją z jednym parametrem, który powinien być wypełniony przez rzeczy (to jedyny powód, dla którego nie należy używać klasycznej pętli while).
źródło
while True: stuff(); if not condition(): break
to bardzo dobry pomysł. Dziękuję Ci!Oto bardziej szalone rozwiązanie o innym wzorze - wykorzystujące coroutines. Kod jest nadal bardzo podobny, ale z jedną ważną różnicą; w ogóle nie ma warunków wyjścia! Coroutine (tak naprawdę łańcuch coroutines) po prostu przestaje, kiedy przestajesz karmić go danymi.
Powyższy kod zbiera wszystkie żetony jak w krotki
tokens
i zakładam nie ma różnicy pomiędzy.append()
i.add()
w oryginalnym kodzie.źródło
Sposób, w jaki to zrobiłem, jest następujący ...
Wydaje mi się, że to proste rozwiązanie, jestem zaskoczony, że jeszcze go tu nie widziałem. Można to oczywiście również odwrócić
itp.
źródło
dla pętli do - while zawierającej instrukcje try
alternatywnie, gdy nie ma potrzeby stosowania klauzuli „w końcu”
źródło
źródło
stuff
funkcji lub powtarzania treści kodu.while condition:
dlatego, żeis True
implikowane.condition
zależy od jakiejś wewnętrznej zmiennejstuff()
, ponieważ ta zmienna nie jest w tym momencie zdefiniowana.Szybki hack:
Użyj tak:
źródło
Dlaczego po prostu nie zrobisz
?
źródło
Sprawdź, czy to pomoże:
Ustaw flagę w module obsługi wyjątków i sprawdź ją przed rozpoczęciem pracy na s.
źródło
while not flagBreak:
i usuwającif (flagBreak) : break
.flag
Unikam zmiennych o nazwie - Nie jestem w stanie wywnioskować, co oznacza wartość True lub False. Zamiast tego użyjdone
lubendOfIteration
. Kod zmienia się wwhile not done: ...
.Jeśli masz scenariusz, w którym zapętlasz się, gdy zasób jest niedostępny lub coś podobnego, co rzuca wyjątek, możesz użyć czegoś takiego
źródło
Dla mnie typowa pętla while będzie taka:
Mógłbym również włączyć pętlę for .. w pętli while, jeśli sytuacja tego wymaga, do zapętlenia innego zestawu warunków.
źródło