range() подробно
range() — не список, а генератор чисел по требованию. Разбираем все три его формы и то, откуда взялось правило «stop не включён».
range() — не список
range() — одна из самых частых причин путаницы у новичков.
Разберёмся сразу и точно.
range(5) создаёт особый объект-генератор чисел — он выдаёт числа по одному, по требованию, а не хранит их все сразу в памяти как список. list(range(5)) действительно даст [0, 1, 2, 3, 4] — но это отдельное, явное превращение, а не то, чем является сам range.Три уровня сигнатуры
| Вызов | Что означает | Пример |
|---|---|---|
range(stop) | от 0 до stop, не включая stop | range(5) → 0, 1, 2, 3, 4 |
range(start, stop) | от start до stop, не включая stop | range(2, 8) → 2, 3, 4, 5, 6, 7 |
range(start, stop, step) | от start до stop с шагом step, не включая stop | range(0, 10, 2) → 0, 2, 4, 6, 8 |
Почему stop не включается
Это не произвольная прихоть языка — это то же самое правило, что мы уже видели в главе 8
у срезов строк. "Python"[0:3] берёт символы с индексами 0, 1, 2 —
и не включает символ с индексом 3. range(0, 3) устроен ровно так
же: 0, 1, 2, без 3. Python последователен: «конец диапазона» везде означает «до этого места,
не включая его».
range(n) всегда даёт ровно n чисел, а длина среза s[a:b] всегда равна b - a — считать количество элементов получается без дополнительных +1/-1 в уме.Шаг: step
Третий аргумент задаёт, на сколько увеличивается (или уменьшается) число на каждом шаге:
for number in range(0, 10, 2):
print(number)
Отрицательный шаг
Шаг может быть отрицательным — тогда числа идут в обратную сторону, но start и stop нужно тоже поменять местами по смыслу: start должен быть больше, чем stop.
for number in range(10, 0, -2):
print(number)
range(10, 0) (без шага) не выдаст ничего — шаг по умолчанию равен +1, а с ним никогда не попасть от 10 вниз к 0. Чтобы диапазон шёл вниз, шаг обязательно должен быть отрицательным и соответствовать направлению.range(0, 10, 0) не зависает и не превращается в бесконечный цикл — Python сразу поднимает ValueError: range() arg 3 must not be zero, потому что с нулевым шагом никогда не сдвинуться от start к stop.