Menu
Русский

Функция range() в Python: start, stop, step и счёт в обратную сторону

Как работает range() в Python — start, stop, step, отрицательные диапазоны и почему он ленивый, а не создаёт сразу список.

Инструмент для порождения чисел

range() делает ровно одну вещь — производит последовательность целых чисел. Это главный напарник for-циклов, когда нужно проитерироваться заданное число раз или пройтись по числовому интервалу.

Самая простая форма принимает один аргумент — stop:

main.py
Output
Click Run to see the output here.

Вывод:

0
1
2
3
4

Две детали, которые ловят новичков:

  1. Счёт начинается с 0. range(5) даёт пять чисел, начиная с 0.
  2. Значение stop исключается. range(5) останавливается перед 5 — само 5 не входит.

Эти правила согласуются по всему Python — в срезах, индексации и range. Как только усвоишь «stop не входит», спотыкаться перестанешь.

Три формы

range() принимает один, два или три аргумента:

main.py
Output
Click Run to see the output here.

Step — это размер каждого скачка. range(0, 20, 4) выдаёт каждое четвёртое число. Держи это в голове в следующий раз, когда нужно «каждый второй элемент» или «каждый десятый сэмпл».

Счёт в обратную сторону

Шаг может быть отрицательным, и тогда ты считаешь назад:

main.py
Output
Click Run to see the output here.

Опять же, stop исключается — range(10, 0, -1) останавливается перед 0, а не на 0. Чтобы включить 0, поставь stop равным -1:

main.py
Output
Click Run to see the output here.

range ленив

В Python 3 range() не строит список чисел в памяти. Он возвращает лёгкий range-объект, который производит числа по одному по требованию. Поэтому ты можешь писать:

main.py
Output
Click Run to see the output here.

Миллиард-числовой «range» занимает фактически ноль памяти. Числа генерируются тогда, когда цикл их просит.

Если список чисел действительно нужен — чтобы модифицировать, отсортировать или индексировать за пределами базового — конвертируй явно:

main.py
Output
Click Run to see the output here.

Чаще всего список не нужен. for i in range(...) работает напрямую.

Типичные паттерны

Горстка рецептов, которые ты будешь использовать постоянно:

Сделать что-то n раз.

main.py
Output
Click Run to see the output here.

_ — соглашение со значением «это значение мне не интересно»: Python его не навязывает, но любой читатель поймёт намерение.

Индексировать по последовательности.

Предпочитай enumerate() вместо range(len(...)), но если нужен именно индекс:

main.py
Output
Click Run to see the output here.

Всё равно в большинстве случаев enumerate(items) чище.

Проходить через каждый второй элемент.

main.py
Output
Click Run to see the output here.

Выведет a, c, e. Для простого прореживания, впрочем, синтаксис срезов ещё прямее: items[::2].

Быстро получить числовой список.

main.py
Output
Click Run to see the output here.

Это списковое включение — о нём позже, — но числа поставляет range.

Чем range() не является

Два острых края, которые стоит знать:

  1. range производит только целые. Если нужен вещественный шаг (например, от 0.0 до 1.0 с шагом 0.1) — используй numpy.arange или цикл со своим счётчиком.
  2. range не работает с произвольными итерируемыми. Он строго для целых чисел. Если ты пытаешься «range-нуть» по списку — тебе нужен enumerate или просто сам список.

Собираем вместе

Небольшой пример, использующий несколько вариаций разом:

main.py
Output
Click Run to see the output here.

Два вложенных цикла на range, дающие сетку. Заметь, что оба цикла стартуют с 1 — range(1, 6), — потому что мы хотим метки от 1 до 5.

Переходим к коллекциям

Ты уже видел условия, оба типа циклов и range. Этого достаточно, чтобы управлять любой коллекцией. Следующая глава — сами коллекции: списки, кортежи, множества и словари.

Часто задаваемые вопросы

Что делает range() в Python?

range() производит последовательность целых чисел. range(n) даёт числа от 0 до n-1. range(start, stop) — целые от start до, но не включая stop. range(start, stop, step) позволяет выбрать шаг, включая отрицательный для счёта в обратную сторону.

range() создаёт список?

Нет. В Python 3 range() возвращает лёгкий range-объект, генерирующий числа по требованию. Поэтому range(10**9) мгновенен — он не выделяет миллиард целых. Оберни в list(...), если список действительно нужен.

Как считать в обратную сторону с range()?

Используй отрицательный шаг: range(10, 0, -1) даёт 10, 9, 8, ..., 1. Помни, что stop всегда исключается, так что чтобы включить 0, пиши range(10, -1, -1).

Учитесь программировать с Coddy

НАЧАТЬ