Narzędzie do tworzenia liczb
range() robi dokładnie jedną rzecz: tworzy ciąg liczb całkowitych. To podstawowy partner pętli for, gdy chcesz powtórzyć coś określoną liczbę razy albo przejść po przedziale liczbowym.
Najprostsza forma przyjmuje jeden argument, wartość stop:
Wynik:
0
1
2
3
4
Dwa szczegóły, które zaskakują nowicjuszy:
- Liczenie zaczyna się od 0.
range(5)daje pięć liczb, zaczynając od 0. - Wartość stop nie wchodzi do wyniku.
range(5)zatrzymuje się przed 5 i nie zawiera samej piątki.
Te zasady są spójne w wycinkach, indeksowaniu i range w całym Pythonie. Gdy przyswoisz sobie, że "stop jest wyłączony", przestanie cię to zaskakiwać.
Trzy formy
range() przyjmuje jeden, dwa albo trzy argumenty:
Step to wielkość każdego skoku. range(0, 20, 4) daje co czwartą liczbę. Pamiętaj o tym, gdy następnym razem będziesz potrzebować "co drugiego elementu" albo "co dziesiątej próbki".
Odliczanie w dół
Krok może być ujemny, co pozwala liczyć wstecz:
Znowu: stop nie wchodzi do wyniku, więc range(10, 0, -1) zatrzymuje się przed 0, a nie na 0. Żeby uwzględnić 0, ustaw stop na -1:
range jest leniwe
W Pythonie 3 range() nie buduje listy liczb w pamięci. Zwraca lekki obiekt range, który wytwarza liczby po jednej, na żądanie. Dlatego możesz napisać:
"Zakres" z miliardem liczb nie zajmuje praktycznie żadnej pamięci. Liczby są generowane wtedy, gdy pętla o nie prosi.
Jeśli naprawdę potrzebujesz listy liczb, bo chcesz ją zmieniać, sortować albo indeksować w bardziej zaawansowany sposób, zamień ją wprost:
Zwykle lista nie jest potrzebna. for i in range(...) działa bezpośrednio.
Typowe wzorce
Kilka przepisów, których będziesz używać bez przerwy:
Zrób coś n razy.
_ to konwencja oznaczająca "ta wartość mnie nie interesuje". Python jej nie wymusza, ale każdy czytelnik rozpozna zamiar.
Indeksowanie sekwencji.
Wybieraj enumerate() zamiast range(len(...)), ale gdy potrzebujesz właśnie samego indeksu:
Mimo to zwykle enumerate(items) jest czytelniejsze.
Przechodzenie po co drugim elemencie.
To wypisuje a, c, e. Przy prostym wycinaniu jeszcze bardziej bezpośrednia jest jednak składnia wycinków: items[::2].
Szybkie tworzenie listy liczb.
To list comprehension, omówiona później, ale liczby dostarcza właśnie range.
Czym range() nie jest
Dwie ostre krawędzie, o których warto wiedzieć:
rangetworzy tylko liczby całkowite. Jeśli potrzebujesz kroków zmiennoprzecinkowych (na przykład od 0.0 do 1.0 co 0.1), użyjnumpy.arangealbo pętli z własnym licznikiem.rangenie działa z dowolnymi obiektami iterowalnymi. Służy konkretnie do liczb całkowitych. Jeśli próbujesz "przejść range'em" po liście, prawdopodobnie szukaszenumeratealbo po prostu samej listy.
Wszystko razem
Mały przykład, który łączy kilka wariantów naraz:
Dwie zagnieżdżone pętle oparte na range tworzą siatkę. Zauważ, że obie pętle zaczynają od 1, range(1, 6), bo chcemy etykiet od 1 do 5.
Przejście do kolekcji
Znasz już warunki, oba rodzaje pętli i range. To wystarczy sterowania przepływem, żeby obsłużyć dowolną kolekcję. Następny rozdział: same kolekcje, czyli listy, krotki, zbiory i słowniki.
Najczęściej zadawane pytania
Co robi range() w Pythonie?
range() tworzy ciąg liczb całkowitych. range(n) daje liczby od 0 do n-1. range(start, stop) daje liczby całkowite od start aż do stop, bez stop. range(start, stop, step) pozwala wybrać wielkość kroku, także ujemną, żeby odliczać w dół.
Czy range() tworzy listę?
Nie. W Pythonie 3 range() zwraca lekki obiekt range, który generuje liczby na żądanie. Dlatego range(10**9) działa natychmiast: tak naprawdę nie rezerwuje miliarda liczb. Opakuj go w list(...), jeśli naprawdę potrzebujesz listy.
Jak odliczać w dół z range() w Pythonie?
Użyj ujemnego kroku: range(10, 0, -1) liczy 10, 9, 8, ..., 1. Pamiętaj, że wartość stop nigdy nie wchodzi do wyniku, więc żeby uwzględnić 0, potrzebujesz range(10, -1, -1).