Pętla for w Pythonie to "dla każdego"
Jeśli znasz język w stylu C, pętla for w Pythonie będzie wyglądać inaczej. Nie ma wzorca z licznikiem for (i = 0; i < n; i++). for w Pythonie to wyłącznie pętla dla każdego: dajesz jej kolekcję, a ona podaje ci elementy po jednym.
To wypisuje trzy linie. Python czyta listę, wyciąga po kolei każdy element i wiąże go z color na czas wykonania ciała. Gdy nic nie zostanie, pętla się kończy.
Zwróć uwagę na kształt: for <name> in <iterable>:, a po nim wcięte ciało. Wcięcie, dwukropek, ciało: ta sama struktura co w if.
Co jest iterowalne
W praktyce wszystko, co przechowuje sekwencję wartości. Listy, krotki, napisy, zakresy range, słowniki, zbiory, pliki i większość własnych obiektów, które zbudujesz.
Jednolitość to największa zaleta: jedna składnia, wiele kształtów danych.
Liczenie przez range()
Gdy naprawdę potrzebujesz licznika ("zrób to dziesięć razy" albo "przejdź po indeksach od 0 do 9"), użyj range():
To wypisuje 0, 1, 2, 3, 4. range(stop) liczy od 0 do stop, ale bez niego. range(start, stop) pozwala ustawić wartość początkową, a range(start, stop, step) pozwala określić krok:
Wkrótce będzie osobna strona o range, bo warto zrozumieć go trochę głębiej. Na razie wystarczy, że range(n) daje n iteracji ponumerowanych od 0 do n-1.
enumerate w Pythonie: pętla z indeksem
Częsta potrzeba: "chcę mieć indeks i wartość jednocześnie". Odruch początkującego to range(len(...)), ale Python ma lepsze narzędzie:
enumerate() zwraca pary (index, value). Dwie zmienne po for rozpakowują parę na dwie nazwy: index i color. To dużo czystsze niż:
Jeśli chcesz liczyć od 1 zamiast od 0, przekaż start=1:
zip w Pythonie: iteracja po dwóch sekwencjach naraz
Gdy masz dwie listy tej samej długości i chcesz połączyć je w pary:
zip zatrzymuje się na najkrótszej sekwencji. Jeśli chcesz, żeby szedł dalej i uzupełniał brakujące miejsca wartością None, użyj itertools.zip_longest.
Iteracja po słowniku
Słowniki pozwalają wybrać, po czym przechodzi pętla:
Najczęściej chcesz .items(): dostajesz klucz i wartość razem w jednej czytelnej linii.
break i continue
Czasem chcesz wyjść wcześniej albo pominąć jedną iterację.
break natychmiast kończy pętlę:
Gdy tylko znajdzie się liczba większa od 6, pętla się zatrzymuje. Pozostałe elementy są ignorowane.
continue pomija resztę bieżącej iteracji i przechodzi do następnej:
Obu można używać, choć continue utrudnia śledzenie pętli, gdy jest ich więcej niż jedno. Często prosty if/else czyta się lepiej.
Klauzula else w pętli
Python ma coś, czego nie ma większość języków: klauzulę else w pętlach. Wykonuje się, gdy pętla zakończy się bez natrafienia na break.
Przydatne, ale na początku mylące. Nie musisz tego używać: flaga logiczna poza pętlą jest często czytelniejsza dla nowych czytelników.
Modyfikowanie listy podczas iteracji
Jedna pułapka warta uwagi: nie dodawaj ani nie usuwaj elementów listy, po której akurat iterujesz. Iteracja gubi się w tym, które indeksy są nadal poprawne, więc albo pominiesz elementy, albo wywołasz błąd. Bezpieczny wzorzec to zbudowanie nowej listy:
Albo, gdy poczujesz się pewniej, list comprehension robi to samo w jednej linii. Omówimy to w rozdziale o kolekcjach.
Mały przykład od początku do końca
Połączmy kilka z tych rzeczy: odczyt listy, filtrowanie, numerowanie, wypisywanie:
Dalej: pętla while
for to właściwy wybór, gdy wiesz, po czym iterujesz. while to właściwy wybór, gdy pętla ma działać, dopóki nie zmieni się jakiś warunek. O tym jest następna strona.
Najczęściej zadawane pytania
Jak działa pętla for w Pythonie?
for item in sequence: wykonuje wcięte ciało raz dla każdego elementu sekwencji, a item przyjmuje po kolei każdą wartość. Sekwencje to między innymi listy, krotki, napisy, słowniki, zakresy range i każdy obiekt, który definiuje iterator.
Czym różni się break od continue?
break natychmiast kończy pętlę i pomija wszystkie pozostałe iteracje. continue pomija resztę bieżącej iteracji i przechodzi do następnej. break znaczy "koniec", a continue znaczy "pomiń ten element".
Jak zrobić pętlę z indeksem w Pythonie?
Opakuj sekwencję w enumerate(...), żeby dostać pary (index, value): for i, item in enumerate(items):. To dużo czystsze niż prowadzenie własnego licznika z i += 1 na końcu pętli.