for row in b:
for drug in drug_input:
for brand in brand_names[drug]:
z trzeciej pętli Jak wyjść z pętli prądowej i przejść do następnej wartości for row in b:
?python: wyjście z dwóch pętli
for row in b:
for drug in drug_input:
for brand in brand_names[drug]:
z trzeciej pętli Jak wyjść z pętli prądowej i przejść do następnej wartości for row in b:
?python: wyjście z dwóch pętli
Ten wykorzystuje logiczną, aby sprawdzić, czy są jeszcze zrobione:
done = False
for x in xs:
for y in ys:
if bad:
done = True
break
if done:
break
ten będzie continue
jeśli przerwa nie był używany. else
zostanie pominięty, jeśli nastąpiła przerwa, więc zobaczy następny break
. Takie podejście ma tę zaletę, że nie trzeba używać zmiennej, ale niektórym może być trudniej ją odczytać.
for x in xs:
for y in ys:
if bad:
break
else:
continue
break
Cóż, miał trzy pętle, a nie dwie. –
Cóż, pomyślałem, że być może OP może być w stanie ekstrapolować do trzech pętli. –
@Teodor: przeczytaj q. ostrożnie - najbardziej zewnętrzna pętla nie musi być wychodząca, więc przykładowa pętla w/2 jest słuszna, dobry komentarz –
Nietestowane:
inner_termination=False
for row in b:
for drug in drug_input:
for brand in brand_names[drug]:
<blah>
if break_condition:
inner_termination=True
break
<blah>
if inner_termination:
inner_termination=False
break
for row in b:
more_drugs = True
for drug in drug_input:
for brand in brand_names[drug]:
if something:
more_drugs = False
break
if not more_drugs:
break
Python nie posiada strukturę sterowania za złamanie z dwóch pętli na raz, więc trzeba zrobić coś takiego podręcznika.
@cjrh: Jestem ciekawy: dlaczego miałbyś pisać "Świetna odpowiedź "ale nie głosuj w górę odpowiedzi? Bez presji ... –
Czy widzisz moją odpowiedź? –
Ah, teraz rozumiem! :) –
Jeśli masz trzy poziomy pętli w jednej metodzie, prawdopodobnie będziesz musiał ponownie przemyśleć swój projekt.
all
i any
, aby uniknąć pisania jawnych pętli.Wykonanie jednego z nich powinno oznaczać, że problem nie występuje.
Nie jestem pewien, czy się z tym zgadzam, szczególnie w przypadku iteracji złożonej struktury danych. Czasami masz słowniki w słownikach w słownikach! – katrielalex
@karielalex: Nie zgadzasz się z tymi dwoma punktami, czy tylko z drugim? –
"Jeśli masz trzy poziomy pętli w jednej metodzie, prawdopodobnie musisz przemyśleć swój projekt." Myślę, że jest różnica między przypadkiem iteracji nad strukturą danych - w takim przypadku wielokrotna iteracja jest semantycznie jedną sekcją i nie należy jej rozdzielać ani przycinać - i przypadkiem, gdy zbyt wiele robi się w jednym miejscu . W tej ostatniej sytuacji zgadzam się z obydwoma punktami. Na przykład ostatnio zbudowałem DFA, który miał tabelę przejściową 'initial node' ->' arc type' -> 'guard' ->' final node'. Do iteracji na wszystkich krawędziach potrzebne są trzy pętle! – katrielalex
for row in b:
ok = True
for drug in drug_input:
if not ok:
break;
for brand in brand_names[drug]:
if not ok:
break
if whatever:
ok = False
try
/except
/raise
, jak sugeruje w komentarzu @ gddc, znajduje się jedna z możliwości. Innym jest do „zawijania” dwa do jednego zagnieżdżonej pętli:
for row in b:
for brand in (b for d in drug_input for b in brand_names[d]):
...
Teraz, break
z for brand
zagnieżdżonej pętli powróci do poziomu zewnętrznej pętli for row
. Oczywiście działa to tylko wtedy, gdy kod, który jest tutaj zastąpiony przez ...
, nie musi widzieć nazwy drug
związanej z badanym lekiem. Czy tak właśnie jest w twoim przypadku?
Wystarczająco prosty, aby uzyskać nazwa leku jest wymagana. 'dla marki, leku w ((b, d) dla d in drug_input dla b w brand_namames [d]):' –
Chciałbym rozważyć umieszczenie dwóch wewnętrznych pętli w funkcji i użycie stamtąd powrotu. Prawdopodobnie przemyślenie tego, co robisz i jak daje lepszą alternatywę do tego.
Czy możesz podać swój aktualny pseudo kod, dane wejściowe i wyjściowe, abyśmy mogli usunąć potrzebę przerwania na pierwszym miejscu? Musimy zobaczyć, gdzie zmienne pętli są używane lub jeszcze lepiej, jaki jest cel przetwarzania.
obsługa wyjątków uderzeń ustawienie zmiennych wszędzie IMO
for row in b:
for drug in drug_input:
try:
for brand in brand_names[drug]:
if some_condition:
raise StopIteration
except StopIteration:
break
Wyjątki są tylko w wyjątkowych sytuacjach! –
"To pochodzi od wyjątku, a nie od standardowego błędu, ponieważ nie jest uważane za błąd w jego normalnej aplikacji." http://docs.python.org/library/exceptions.html#exceptions.StopIteration – brianz
OK, to był całkiem dobry powrót :) Ale poważnie, nie obsługuj wyjątków dla przepływu sterowania. W dowolnym języku. Funkcja próbna z wyjątkiem jest bardzo, bardzo rozpowszechnionym wizualnym sygnałem, że "wydarzyło się coś niezwykłego". –
Najnowsze PEP widzę zainteresowanie tej funkcji jest 3136 (i została odrzucona): http://mail.python.org/pipermail/python-3000/2007-July/008663.html
Sąsiednie & najczystszych co mogę zobaczyć, co chcesz zrobić, to wykonać następujące czynności (a ponieważ nawet nazwy typów mają zasięg, możesz zadeklarować LocalBreak w funkcji, której potrzebuje):
class LocalBreak(Exception): pass
try:
for i in ...:
for h in ...:
for j in ...:
if should_break(j):
raise LocalBreak()
except LocalBreak:
pass
for a in aa:
for b in bb:
for c in cc:
if c == a[b]:
break
else:
continue
break
Python obsługuje oświadczenia for...else
. else
blok jest oceniany, jeśli wewnętrzny break
nie został uruchomiony.
Przepraszam, czy możesz mi powiedzieć, proszę, co to dodaje do aktualnej treści? –
Jeśli masz zbyt wiele osadzonych pętli, może to być czas na refaktor. W tym przypadku uważam, że najlepszym refaktorem jest przeniesienie twoich pętli do funkcji i użycie instrukcji return
. To wymusi wyjście z dowolnej liczby pętli. Na przykład:
def example(self, drug_input):
ok = False
for x in drug_input["names"]:
for y in range(drug_input["number_of_drugs"]):
for z in drug_input["list_of_drugs"]:
# do stuff
if ok:
return drug_costs
Teraz, być może zmieniając logika jak to jest trudne, ale założę refaktoring pomoże w inny sposób.
Prawdopodobnie chciałbym owijać ten blok próbując go wyrwać z podbiciem. –
proszę, pokaż mi, w jaki sposób –
Czy mogę zapytać, jaki stan w wewnętrznej pętli wymusi "przerwę"? –