Rozumiem, jak działa ten konstrukt:
for i in range(10):
print(i)
if i == 9:
print("Too big - I'm giving up!")
break;
else:
print("Completed successfully")
Ale nie rozumiem, dlaczego else
użyto tutaj słowa kluczowego, ponieważ sugeruje, że dany kod działa tylko wtedy, gdy for
blok nie zostanie ukończony, co jest przeciwieństwem tego, co robi! Bez względu na to, jak o tym myślę, mój mózg nie może płynnie przechodzić od for
wypowiedzi do else
bloku. Dla mnie, continue
czy continuewith
miałoby to więcej sensu (i staram się trenować, aby czytać to jako takie).
Zastanawiam się, jak kodery Pythona odczytują ten konstrukt w swojej głowie (lub głośno, jeśli chcesz). Być może brakuje mi czegoś, co ułatwiłoby rozszyfrowanie takich bloków kodu?
python
if-statement
for-loop
for-else
Kent Boogaart
źródło
źródło
break
jest często używany w pętlach „znalazłem to” , możesz przetłumaczyć go na „jeśli nie znaleziono” , co nie jest dalekie od tego, coelse
czytafor ... else foo()
po prostu wprowadzeniemfoo()
pętli for?”. Odpowiedź brzmi: zachowują się inaczej tylko wtedy, gdy pętla zawierabreak
(jak opisano szczegółowo poniżej).Odpowiedzi:
To dziwna konstrukcja nawet dla doświadczonych programistów Pythona. W połączeniu z pętlami for oznacza po prostu „znajdź jakiś element w iteracji, w przeciwnym razie, jeśli żaden nie zostanie znaleziony, wykonaj…”. Jak w:
Ale za każdym razem, gdy zobaczysz ten konstrukt, lepszą alternatywą jest albo kapsułkowanie wyszukiwania w funkcji:
Lub skorzystaj ze zrozumienia listy:
Nie jest semantycznie równoważny z pozostałymi dwiema wersjami, ale działa wystarczająco dobrze w niekrytycznym kodzie krytycznym, gdzie nie ma znaczenia, czy iterujesz całą listę, czy nie. Inni mogą się nie zgadzać, ale ja osobiście unikałbym używania bloków for-else lub while-else w kodzie produkcyjnym.
Zobacz także [Python-ideas] Podsumowanie dla ... innych wątków
źródło
for
przykładach z pętli, i chcesz użyć wyrażenia / listy do generatora, tonext((o for o in objects if o.key == search_key), None)
lub zawiń go wtry
/except
i nie używaj wartości domyślnej zamiastif
/else
.for/else
konstruktu.else
sparowałem się zfor
i nie miałem pojęcia, że to legalne.break
instrukcja działa w trybie jawności, jak w tym przykładzie. Z powyższych dokumentów: „else
Klauzula ma inny dostrzegany problem: jeśli nie ma jejbreak
w pętli,else
klauzula jest funkcjonalnie redundantna.”. np.for x in [1, 2, 3]:\n print x\n else:\n print 'this executes due to no break'
Typową konstrukcją jest uruchamianie pętli, dopóki coś nie zostanie znalezione, a następnie wyrwanie się z pętli. Problem polega na tym, że jeśli wyjdę z pętli lub końców pętli, muszę ustalić, który przypadek się wydarzył. Jedną z metod jest stworzenie zmiennej flag lub store, która pozwoli mi wykonać drugi test, aby zobaczyć, jak pętla została zamknięta.
Załóżmy na przykład, że muszę przeszukać listę i przetworzyć każdy element, aż zostanie znaleziony element flagi, a następnie przerwać przetwarzanie. Jeśli brakuje elementu flagi, należy zgłosić wyjątek.
Korzystając z konstrukcji Pythona
for
...else
maszPorównaj to z metodą, która nie używa tego cukru syntaktycznego:
W pierwszym przypadku
raise
jest ściśle związany z pętlą for, z którą współpracuje. W drugim przypadku wiązanie nie jest tak silne i podczas konserwacji można wprowadzić błędy.źródło
Python: the good parts
książka.process(i)
przypadku zdarza się to dla każdego przedmiotumylist
wcześniejtheflag
, a nie dlatheflag
siebie? Czy to jest to, co było zamierzone?process
wykona się na każdym,i
który istnieje na liście przedtheflag
osiągnięciem, nie zostanie wykonany na elementach na liście późniejtheflag
i nie zostanie wykonanytheflag
.Istnieje doskonała prezentacja Raymonda Hettingera, zatytułowana Transforming Code into Beautiful, Idiomatic Python , w której krótko omawia historię
for ... else
konstruktu. Odpowiednią sekcją jest „Rozróżnianie wielu punktów wyjścia w pętlach”, zaczynając od 15:50 i kontynuując przez około trzy minuty. Oto najważniejsze punkty:for ... else
Konstrukt został opracowany przez Donald Knuth jako zamiennik dla niektórychGOTO
przypadków zastosowania;else
słów kluczowych sens, ponieważ „to, co kiedyś Knuth, a ludzie wiedzieli, w tym czasie, wszystkie [for
wypowiedzi] był osadzonyif
iGOTO
pod spodem, i oczekuje się, żeelse
”;Więc jeśli pytanie brzmi: „Dlaczego nie zmienią tego słowa kluczowego?” wtedy Cat Plus Plus prawdopodobnie udzielił najdokładniejszej odpowiedzi - w tym momencie byłoby to zbyt destrukcyjne dla istniejącego kodu, aby było praktyczne. Ale jeśli pytanie, które naprawdę zadajesz, brzmi: dlaczego
else
zostało ponownie użyte, cóż, najwyraźniej wydawało się to wtedy dobrym pomysłem.Osobiście podoba mi się kompromis polegający na komentowaniu
# no break
w miejscu, gdzieelse
na pierwszy rzut oka można się pomylić z przynależnością do pętli. Jest dość jasny i zwięzły. Ta opcja otrzymuje krótką wzmiankę w podsumowaniu, do którego Bjorn podłączył na końcu swojej odpowiedzi:* Cytat bonusowy z tej części filmu: „Tak jak gdybyśmy nazwali funkcję makrofagów, nikt nie zapytałby:„ Co robi lambda? ”.
źródło
Ponieważ nie chcieli wprowadzić nowego słowa kluczowego do języka. Każdy z nich kradnie identyfikator i powoduje problemy ze zgodnością wsteczną, więc zwykle jest to ostateczność.
źródło
finally
że w takim przypadku byłby lepszy wybór. Czy w chwili wprowadzenia tego konstruktu słowo kluczowe nie było jeszcze obecne?finally
nie jest dużo lepszy, ponieważ sugeruje, że blok będzie zawsze wykonywany po pętli, a tak nie jest (ponieważ byłoby to zbędne po prostu uruchamiając kod po pętli).finally
ponieważ klauzula else jest wykonywana także wtedy, gdycontinue
jest używana w pętli for - to możliwe, że wiele razy i nie tylko na końcu.else
wykonanie klauzuli @pepr nie ma wpływucontinue
( dokumenty i kod testowy )else
Jest wykonywana tylko wtedy, gdycontinue
był jednym z ostatniej iteracji.Upraszczając, możesz tak o tym myśleć;
break
polecenie wfor
pętli,else
część nie zostanie wywołana.break
polecenia wfor
pętli,else
część zostanie wywołana.Innymi słowy, jeśli iteracja pętli nie zostanie „zerwana”
break
,else
część zostanie wywołana.źródło
else
Blok również nie będą wykonywane, jeżeli korpus pętli zgłasza wyjątek.Najłatwiejszym sposobem, aby „dostać” to, co zrobił for / else, a co ważniejsze, kiedy go użyć, było skoncentrowanie się na tym, do czego przeskakuje instrukcja break. Konstrukcja For / else jest pojedynczym blokiem. Przerwa wyskakuje z bloku i przeskakuje „nad” klauzulą else. Gdyby treść klauzuli else była po prostu zgodna z klauzulą for, nigdy nie byłaby przeskakiwana, więc należałoby podać równoważną logikę, umieszczając ją w if. To zostało powiedziane wcześniej, ale nie do końca w tych słowach, więc może pomóc komuś innemu. Spróbuj uruchomić następujący fragment kodu. Z całego serca opowiadam się za komentarzem „bez przerwy” za jasność.
źródło
for:
/else:
, tak naprawdę nie uzasadnia tego słowa kluczowegoelse
. Biorąc pod uwagę ramy podane tutaj,then:
wydaje się, że byłoby to znacznie bardziej naturalne. (Nie są powody doelse
bycia wybranym, podane w innych odpowiedzi - nie są one tylko pod warunkiem, tutaj.)Myślę, że dokumentacja zawiera świetne wyjaśnienie innych kwestii , kontynuuj
Źródło: Dokumentacja Python 2: Samouczek dotyczący przepływu sterowania
źródło
Przeczytałem coś w stylu:
Jeśli jeszcze warunków do uruchomienia pętli, robić rzeczy, jeszcze coś innego.
źródło
for:
/else:
sprawia, że brzmi to tak, jakbyelse:
zawsze działało po pętli, co nie jest prawdą.Ponieważ na część techniczną udzielono odpowiedzi, mój komentarz jest po prostu związany z zamieszaniem, które wywołuje to słowo kluczowe z recyklingu .
Ponieważ Python jest bardzo wymownym językiem programowania, niewłaściwe użycie słowa kluczowego jest bardziej znane.
else
Kluczowe doskonale opisuje część strumienia drzewa decyzyjnego „jeśli nie można to zrobić, (jeszcze) zrobić”. Jest to sugerowane w naszym własnym języku.Zamiast tego użycie tego słowa kluczowego z instrukcjami
while
ifor
powoduje zamieszanie. Powód, dla którego nasza kariera programistów nauczyła nas, żeelse
oświadczenie znajduje się w drzewie decyzyjnym; jego zakres logiczny , opakowanie, które warunkowo zwraca ścieżkę do naśladowania. Tymczasem instrukcje pętli mają konkretny, wyraźny cel, aby coś osiągnąć. Cel jest osiągany po ciągłej iteracji procesu.if / else
wskaż ścieżkę, którą chcesz podążać . Pętle podążają ścieżką aż do osiągnięcia „celu” .Problem polega na tym, że
else
jest to słowo, które jasno definiuje ostatnią opcję w warunku. W semantykę tego słowa są zarówno dzielone przez Python i Human Language. Ale słowo „inaczej” w języku ludzkim nigdy nie jest używane do wskazania działań, które ktoś lub coś podejmie po zakończeniu. Zostanie wykorzystany, jeśli w trakcie jego uzupełniania pojawi się problem (bardziej jak instrukcja break ).Na koniec słowo kluczowe pozostanie w języku Python. Jest jasne, że to był błąd, wyraźniej, gdy każdy programista próbuje wymyślić historię, aby zrozumieć jej użycie jak jakieś urządzenie mnemoniczne. Bardzo bym chciał, gdyby zamiast tego wybrali słowo kluczowe
then
. Uważam, że to słowo kluczowe idealnie pasuje do tego iteracyjnego przepływu, który jest opłacalny po pętli.Przypomina to sytuację, którą ma dziecko po każdym kroku montażu zabawki: A NASTĘPNIE tato?
źródło
Przeczytałem to tak, jak: „Gdy
iterable
całkowicie się wyczerpie, a wykonanie zakończy się po następnej instrukcjifor
, klauzula else zostanie wykonana”. Zatem, gdy iteracja zostanie przerwanabreak
, nie zostanie to wykonane.źródło
Zgadzam się, to bardziej jak „elif nie [warunek (y) podnoszenia przerwy]”.
Wiem, że to stary wątek, ale teraz zastanawiam się nad tym samym pytaniem i nie jestem pewien, czy ktoś uchwycił odpowiedź na to pytanie w sposób, w jaki je rozumiem.
Dla mnie istnieją trzy sposoby „czytania” THE
else
sięFor... else
lubWhile... else
oświadczenia, z których wszystkie są równoważne, to:else
==
if the loop completes normally (without a break or error)
else
==
if the loop does not encounter a break
else
==
else not (condition raising break)
(przypuszczalnie jest taki warunek, inaczej nie miałbyś pętli)Zasadniczo „else” w pętli jest tak naprawdę „elif ...”, gdzie „...” oznacza (1) brak przerwy, co jest równoważne (2) NIE [warunkowi (-om) podniesienia przerwy].
Myślę, że kluczem jest to, że nie
else
ma sensu bez „przerwy”, więc afor...else
obejmuje:Tak więc podstawowe elementy
for...else
pętli są następujące i można je czytać w prostszym języku angielskim jako:Jak powiedzieli inni plakaty, przerwa jest generalnie generowana, gdy jesteś w stanie zlokalizować to, czego szuka twoja pętla, więc
else:
staje się „co zrobić, jeśli nie można zlokalizować elementu docelowego”.Przykład
Możesz także używać obsługi wyjątków, przerw i pętli.
Wynik
Przykład
Prosty przykład z uderzeniem przerwy.
Wynik
Przykład
Prosty przykład, w którym nie występuje przerwa, brak warunku podniesienia przerwy i nie występuje błąd.
Wynik
źródło
else
Kluczowe może być tu mylące, i jak wiele osób podkreśliło, coś podobnegonobreak
,notbreak
jest bardziej odpowiednie.Aby zrozumieć
for ... else ...
logicznie, porównaj to ztry...except...else
, nieif...else...
, większość programistów pythonowych zna następujący kod:Podobnie pomyśl o
break
szczególnym rodzajuException
:Różnica jest
python
implikowanaexcept break
i nie można jej zapisać, więc staje się:Tak, wiem, że to porównanie może być trudne i męczące, ale wyjaśnia zamieszanie.
źródło
Kody w
else
bloku instrukcji zostaną wykonane, gdyfor
pętla nie zostanie przerwana.Z dokumentacji: przerywaj i kontynuuj Instrukcje, a także Klauzule dotyczące pętli
źródło
Oto sposób, aby pomyśleć o tym, o czym nikt inny nie wspominał powyżej:
Po pierwsze, pamiętaj, że pętle for to po prostu cukier syntaktyczny wokół pętli while. Na przykład pętla
można przepisać (w przybliżeniu) jako
Po drugie, pamiętaj, że pętle while są w zasadzie powtarzanymi blokami if! Zawsze możesz odczytać pętlę while jako „jeśli ten warunek jest spełniony, wykonaj treść, a następnie wróć i sprawdź ponownie”.
Tak więc, podczas gdy / else ma doskonały sens: jest to dokładnie taka sama struktura, jak w przypadku / else, z dodatkową funkcją zapętlania, aż warunek stanie się fałszywy, zamiast tylko sprawdzać warunek raz.
I wtedy for / else ma również sens: ponieważ wszystkie pętle for są po prostu cukrem syntaktycznym na szczycie pętli while, wystarczy dowiedzieć się, jakie są ukryte warunki warunkowe pętli while, a wtedy pozostałe odpowiada, kiedy to stan staje się Fałszywy.
źródło
Świetne odpowiedzi to:
Moja notatka pochodzi z tego, co powiedział kiedyś Donald Knuth (przepraszam, nie mogę znaleźć odniesienia), że istnieje konstrukcja, w której while-else jest nie do odróżnienia od if-else, a mianowicie (w Pythonie):
ma taki sam przepływ (z wyłączeniem różnic niskiego poziomu) jak:
Chodzi o to, że if-else może być uważany za cukier składniowy dla while-else, który ukryty jest
break
na końcu jegoif
bloku. Przeciwna implikacja, że tawhile
pętla jest przedłużeniemif
, jest bardziej powszechna (jest to po prostu powtarzanie / zapętlona kontrola warunkowa), ponieważif
często jest nauczana wcześniejwhile
. Nie jest to jednak prawdą, ponieważ oznaczałoby toelse
blokowanie w czasie, w którym -w przeciwnym razie byłby wykonywany za każdym razem, gdy warunek jest fałszywy.Aby ułatwić ci zrozumienie, pomyśl o tym w ten sposób:
Kolejna uwaga:
źródło
Możesz pomyśleć o tym tak,
else
jak w pozostałej części lub o innych rzeczach, które nie zostały zrobione w pętli.źródło
„else” tutaj jest szalenie proste, po prostu wredne
1, „jeśli
for clause
ukończono”Potrafi pisać tak długie stwierdzenia, że „klauzula jest zakończona”, więc wprowadzają „else”.
else
tutaj jest w swojej naturze.2, ale co powiesz na
for clause is not run at all
Więc to całkowicie stwierdzenie jest kombinacją logiczną:
lub ujmując to w ten sposób:
lub w ten sposób:
źródło
Oto kolejny idiomatyczny przypadek użycia oprócz wyszukiwania. Powiedzmy, że chcesz poczekać na spełnienie warunku, np. Otwarcie portu na zdalnym serwerze wraz z pewnym czasem oczekiwania. Następnie możesz użyć takiej
while...else
konstrukcji:źródło
Chciałem po prostu znów to zrozumieć. Odkryłem, że następujące pomaga!
• Pomyśl o
else
sparowaniu zif
wewnętrzną pętlą (zamiast zfor
) - jeśli warunek jest spełniony, przerwij pętlę, w przeciwnym razie zrób to - z wyjątkiem tego, że jestelse
sparowany z wielomaif
s!• Jeśli nie ma żadnych
if
satysfakcji, zrób toelse
.• Wielokrotność
if
s może być również uważana zaif
-elif
s!źródło
Uważam strukturę jak w przypadku (jeśli) A inny B, a dla (jeśli) -else jest specjalny if-else , z grubsza . Może pomóc zrozumieć inaczej .
A i B są wykonywane najwyżej raz, co jest tym samym co struktura if-else.
for (if) można uznać za specjalny if, który wykonuje pętlę, aby spróbować spełnić warunek if. Gdy warunek if zostanie spełniony, A i przerwać ; Else , B.
źródło
Python używa pętli „for za” i „while”, więc jeśli nic nie dotyczy pętli, dzieje się coś innego. Na przykład:
Wynik byłby „Cześć” w kółko (jeśli mam rację).
źródło