range() szczegóły
range() nie jest lista, lecz generatorem liczb na żądanie. Przeanalizujmy wszystkie trzy jego formy i skąd wzięła się zasada „stop nie jest uwzględniona”
range() nie jest lista
range() jest jedną z najczęstszych przyczyn zamieszania wśród początkujących.
Ustalmy to od razu i dokładnie.
range(5) tworzy specjalny obiekt generatora liczb — generuje liczby pojedynczo na żądanie, zamiast przechowywać je wszystkie naraz w pamięci jako lista. list(range(5)) naprawdę się ustąpi [0, 1, 2, 3, 4] — ale to jest osobna, oczywista przemiana, a nie tym, czym jest range.Trzy Charakterystyczne Poziomy
| Challenge | Co oznacza | Przykład |
|---|---|---|
range(stop) | od 0 do stop, nie licząc stop | range(5) → 0, 1, 2, 3, 4 |
range(start, stop) | od start do stop, nie wliczając stop | range(2, 8) → 2, 3, 4, 5, 6, 7 |
range(start, stop, step) | od start do stop z krokiem step, nie wliczając stop | range(0, 10, 2) → 0, 2, 4, 6, 8 |
Dlaczego stop nie chce się włączyć
To nie jest dowolna fanaberia języka — to ta sama zasada, którą już widzieliśmy w rozdziale 8
w wycinkach łańcuch znaków. "Python"[0:3] bierze znaki o indeksach 0, 1, 2 — i nie obejmuje znaku o indeksie 3. range(0, 3) jest ułożone dokładnie tak
To samo: 0, 1, 2, bez 3. Python spójne: "koniec zakresu" wszędzie oznacza "do tego miejsca,
bez uwzględnienia tego."
range(n) zawsze daje dokładnie n liczby oraz długość kawałka s[a:b] zawsze jest równy b - a — liczenie ilości elementów wychodzi bez dodatkowych +1/-1 w głowie.Krok: step
Trzeci argument określa, o ile liczba rośnie (lub maleje) na każdym kroku:
for number in range(0, 10, 2):
print(number)
Negatywny krok
Etap może być ujemny – wtedy liczby idą w przeciwnym kierunku, ale start też stop Konieczne jest także zmienienie kolejności zgodnie z jego znaczeniem: start powinno być więcej niż stop.
for number in range(10, 0, -2):
print(number)
range(10, 0) (bez kroku) nic nie zwróci — domyślny krok to +1, a dzięki niemu nigdy nie przejdziesz z 10 do 0. Aby zakres spadł, krok musi być ujemny i odpowiadać kierunkowi.range(0, 10, 0) nie zawiesza się i nie zamienia w nieskończoną pętlę — Python od razu podnosi ValueError: range() arg 3 must not be zerodlatego, że przy zerowym kroku nigdy nie da się przejść z start do stop.