Chciałem wiedzieć, czy są jakieś wbudowane sposoby kontynuowania następnej iteracji w zewnętrznej pętli w Pythonie. Weźmy na przykład pod uwagę kod:
for ii in range(200):
for jj in range(200, 400):
...block0...
if something:
continue
...block1...
Chcę, aby ta instrukcja kontynuowała wyjście z pętli jj i przejście do następnego elementu w pętli ii. Mogę zaimplementować tę logikę w inny sposób (ustawiając zmienną flagową), ale czy istnieje łatwy sposób, aby to zrobić, czy to jest jak proszenie o zbyt wiele?
Odpowiedzi:
W ogólnym przypadku, gdy masz wiele poziomów zapętlenia i
break
nie działa dla Ciebie (ponieważ chcesz kontynuować jedną z górnych pętli, a nie tę tuż nad bieżącą), możesz wykonać jedną z następujących czynnościRefaktoryzuj pętle, z których chcesz uciec, do funkcji
Wadą jest to, że może być konieczne przekazanie tej nowej funkcji pewnych zmiennych, które wcześniej znajdowały się w zakresie. Możesz po prostu przekazać je jako parametry, uczynić z nich zmienne instancji w obiekcie (utwórz nowy obiekt tylko dla tej funkcji, jeśli ma to sens) lub zmienne globalne, pojedyncze elementy, cokolwiek (ehm, ehm).
Lub możesz zdefiniować
inner
jako funkcję zagnieżdżoną i pozwolić jej po prostu przechwytywać to, czego potrzebuje (może być wolniejsze?)Użyj wyjątków
Filozoficznie, do tego służą wyjątki, przerywanie przepływu programu przez strukturalne bloki programistyczne (jeśli, na, podczas), gdy jest to konieczne.
Zaletą jest to, że nie musisz dzielić jednego fragmentu kodu na wiele części. Jest to dobre, jeśli jest to jakieś obliczenie, które projektujesz podczas pisania w Pythonie. Wprowadzenie abstrakcji na tak wczesnym etapie może Cię spowolnić.
Wadą tego podejścia jest to, że autorzy interpreterów / kompilatorów zwykle zakładają, że wyjątki są wyjątkowe i odpowiednio je optymalizują.
Utwórz dla tego specjalną klasę wyjątków, aby nie ryzykować przypadkowego wyciszenia innego wyjątku.
Coś zupełnie innego
Jestem pewien, że istnieją jeszcze inne rozwiązania.
źródło
Break
przerwie pętlę wewnętrzną, a blok 1 nie zostanie wykonany (będzie działać tylko wtedy, gdy pętla wewnętrzna zostanie normalnie zakończona).źródło
for...else
jest często użyteczną konstrukcją, chociaż może być myląca. Pamiętaj tylko, żeelse
w tym kontekście oznacza to „bez przerwy”.W innych językach możesz oznaczyć pętlę i przerwać ją. Propozycja ulepszenia Pythona (PEP) 3136 zasugerowała dodanie ich do Pythona, ale Guido odrzucił to :
Więc jeśli na to liczyłeś, nie masz szczęścia, ale spójrz na jedną z pozostałych odpowiedzi, ponieważ są tam dobre opcje.
źródło
for-else
jest bardziej skomplikowane, trudniejsze do odczytania i prawdopodobnie bardziej nadużywane (jeśli nie zwykły błąd) niż byłyby nazwane pętle. Myślę, że użyłbym innego słowa kluczowego niżelse
- może coś takiegoresume
, jak byłoby dobre? Jesteśbreak
w pętli iresume
jest zaraz po niej?Myślę, że mógłbyś zrobić coś takiego:
źródło
for
,else
przed (a myślę, że większość ludzi, którzy nie pamiętają od szczytu głowy, jak to działa).Myślę, że jednym z najłatwiejszych sposobów osiągnięcia tego jest zastąpienie „kontynuuj” wyrażeniem „przerwa”, tj
Na przykład tutaj jest prosty kod, aby zobaczyć, jak dokładnie to działa:
źródło
Innym sposobem radzenia sobie z tego rodzaju problemem jest użycie Exception ().
Na przykład:
wynik:
Zakładając, że chcemy przeskoczyć do zewnętrznej pętli n z pętli m, jeśli m = 3:
wynik:
Link referencyjny: http://www.programming-idioms.org/idiom/42/continue-outer-loop/1264/python
źródło
Chcemy coś znaleźć, a następnie zatrzymać wewnętrzną iterację. Używam systemu flagowego.
źródło
False:continue
chodzi o ... nietypowe formatowanie. Jak to często bywa w systemach „naturalnych”, gdzie wykładnicza jest normą, wystarczy kilka razy mieć szczęście na SO, aby zgromadzić znaczną ilość punktów reputacji. W każdym razie moje „najlepsze” odpowiedzi są zazwyczaj najmniej popularne.Właśnie zrobiłem coś takiego. Moim rozwiązaniem było zastąpienie wnętrza pętli funkcją rozumienia listy.
gdzie op jest operatorem boolowskim działającym na kombinacji ii i jj. W moim przypadku, jeśli którakolwiek z operacji zakończyła się pomyślnie.
To naprawdę nie różni się zbytnio od dzielenia kodu na funkcję, ale pomyślałem, że użycie operatora „any” do wykonania operacji logicznej OR na liście wartości logicznych i wykonanie logiki w jednej linii było interesujące. Unika również wywołania funkcji.
źródło