Функция range в Python: создание числовых последовательностей

Раздел: range -> Итерации

Работа с range: синтаксис и базовые примеры

Функция range в Python создает неизменяемую последовательность целых чисел. Она широко используется для организации циклов, генерации списков и индексации. Базовый синтаксис включает три формы:

Основное эффективное решение - использование range(start, stop, step) с целыми аргументами. Примеры:

# range(stop) - числа от 0 до stop-1
for i in range(5):
    print(i, end=' ')

Python диапазон чисел (диапазон чисел (range) в python)

0 1 2 3 4
# range(start, stop) - от start до stop-1
list(range(2, 7))
[2, 3, 4, 5, 6]
# range(start, stop, step) - с шагом
list(range(1, 10, 2))
[1, 3, 5, 7, 9]

По умолчанию start=0, step=1. Значения start, stop и step должны быть целыми числами (int). Результат - объект класса range, который в Python 3 является ленивым (не хранит все элементы сразу).

Как получить последовательность чисел от 0 до N-1?

Цель: простой перебор фиксированного количества итераций. Решение: range(N).

N = 10
for i in range(N):
    print(i, end=' ')
0 1 2 3 4 5 6 7 8 9

Типичная ошибка: путаница с границами. Например, ожидание чисел 1..10 при range(10) даст 0..9. Для включения 10 нужно range(1, 11).

Как создать последовательность от A до B (включительно)?

Цель: получить все целые числа в заданном отрезке. Решение: range(A, B+1).

A, B = 5, 8
list(range(A, B+1))
[5, 6, 7, 8]

Проблема: если A > B и step положительный, результат пуст. Для обратного порядка нужен отрицательный шаг.

Как сгенерировать последовательность с шагом, отличным от 1?

Цель: например, только четные числа или прогрессия с шагом 3. Решение: range(start, stop, step).

# Четные от 0 до 10
list(range(0, 11, 2))
[0, 2, 4, 6, 8, 10]
# Числа от 20 до 10 с шагом -5
list(range(20, 9, -5))
[20, 15, 10]

Типичная ошибка: при отрицательном шаге start должно быть больше stop, иначе последовательность пуста. Пример: list(range(5, 1, -1)) работает, а list(range(1, 5, -1)) дает [].

Как получить обратный порядок чисел?

Цель: перебрать числа от большего к меньшему. Решение: range(start, stop-1, -1) или reversed(range(...)).

# Обратный отсчет от 10 до 1
for i in range(10, 0, -1):
    print(i, end=' ')
10 9 8 7 6 5 4 3 2 1
# Альтернатива через reversed
list(reversed(range(1, 11)))
[10, 9, 8, 7, 6, 5, 4, 3, 2, 1]

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

Как использовать range для итерации по индексам списка?

Цель: получить доступ к элементам по индексу, возможно изменять их. Решение: for i in range(len(lst)).

fruits = ['яблоко', 'банан', 'вишня']
for i in range(len(fruits)):
    print(f'Индекс {i}: {fruits[i]}')
Индекс 0: яблоко
Индекс 1: банан
Индекс 2: вишня

Типичная ошибка: изменение длины списка внутри цикла может привести к пропуску элементов или IndexError. Лучше создать копию или использовать enumerate.

Как сразу преобразовать range в список чисел?

Цель: получить материализованный список для случайного доступа или передачи в функцию. Решение: list(range(...)).

numbers = list(range(0, 20, 3))
numbers
[0, 3, 6, 9, 12, 15, 18]

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

Как использовать range в генераторе списка (list comprehension)?

Цель: компактно создать список на основе последовательности. Решение: [выражение for i in range(...)].

squares = [x**2 for x in range(5)]
squares
[0, 1, 4, 9, 16]

Типичная ошибка: попытка использовать нецелые шаги - range(0, 1, 0.1) приведет к TypeError. Для вещественных прогрессий применяют numpy.arange или генератор на while.

Как проверить, входит ли число в диапазон?

Цель: быстрая проверка принадлежности без создания списка. Решение: оператор in работает с range за O(1) благодаря ленивому сравнению границ и шага.

x = 7
if x in range(0, 10, 2):
    print('Четное число от 0 до 8')
else:
    print('Не входит')
Не входит

Проблема: проверка x in range(a, b, s) работает лишь для целых x. Для float или других типов - TypeError. Также не подходит для больших разрывных диапазонов, если нужно учитывать только границы.

Расширенные примеры использования range

Отрицательный шаг с нерегулярным интервалом

Пример
# Степени двойки от 32 до 2 с шагом -2? Нет, step фиксирован.
# Но можно комбинировать с list comprehension:
[x for x in range(32, 1, -2)]
[32, 30, 28, 26, 24, 22, 20, 18, 16, 14, 12, 10, 8, 6, 4, 2]

Здесь step = -2, что дает убывающую арифметическую прогрессию.

Использование range в функции map

Пример
# Преобразование чисел в строки с добавлением префикса
list(map(lambda n: f'Item-{n}', range(3)))
['Item-0', 'Item-1', 'Item-2']

Функция map применяет лямбду к каждому элементу range, возвращая итератор.

Вложенные циклы с range для создания матрицы

Пример
# Матрица 3x4, заполненная произведением индексов
matrix = [[i*j for j in range(4)] for i in range(3)]
matrix
[[0, 0, 0, 0], [0, 1, 2, 3], [0, 2, 4, 6]]

Каждый внутренний список создается с помощью range(4), внешний - range(3).

Генерация дат с помощью range (только номер дня)

Пример
# Упрощенный пример: дни месяца (не учитывая границы месяцев)
for day in range(1, 32):
    if day % 7 == 0:
        print(f'День {day} - воскресенье (модель)')
День 7 - воскресенье (модель)
День 14 - воскресенье (модель)
День 21 - воскресенье (модель)
День 28 - воскресенье (модель)

Для настоящих дат используют модуль datetime.

Итерация по range с помощью iter и next

Пример
r = range(3)
it = iter(r)
print(next(it))
print(next(it))
print(next(it))
0
1
2

Полезно для ручного управления итерацией.

Комбинация range и zip

Пример
# Параллельный перебор двух списков с индексами
names = ['Анна', 'Борис', 'Вика']
scores = [85, 92, 78]
for i, (name, score) in enumerate(zip(names, scores)):
    print(f'{i}: {name} - {score}')
0: Анна - 85
1: Борис - 92
2: Вика - 78

enumerate сам создает счетчик, но если нужен свой шаг, можно использовать zip(range(...), ...).

Генерация чисел с плавающей точкой (имитация)

Пример
# Через list comprehension
float_seq = [x/10 for x in range(0, 11, 2)]
float_seq
[0.0, 0.2, 0.4, 0.6, 0.8, 1.0]

Так получают фиксированный шаг в дробной части. Для произвольных float лучше использовать numpy.

Ошибки при использовании range с нецелыми аргументами

Пример
# Попытка создать range с float
# range(0.5, 10, 0.5)  # TypeError: 'float' object cannot be interpreted as an integer

Решение: привести к int или использовать цикл while.

Проверка принадлежности к диапазону с большим шагом

Пример
# Быстрая проверка: 1000 in range(0, 1000000, 1000) -> True
1000 in range(0, 1000000, 1000), 1500 in range(0, 1000000, 1000)
(True, False)

Оператор in не создает список, а вычисляет по формуле.

Использование range в генераторах (yield from)

Пример
def even_numbers(limit):
    yield from range(0, limit, 2)

list(even_numbers(10))
[0, 2, 4, 6, 8]

Компактная передача последовательности в генератор.

Range и слайсинг (срезы) списка

Пример
# Получить индексы для среза
lst = [10, 20, 30, 40, 50, 60]
indices = range(1, 5, 2)  # 1, 3
[lst[i] for i in indices]
[20, 40]

Хотя проще взять срез lst[1:5:2], понимание range помогает в динамическом формировании индексов.

Диапазон чисел (range) в Python - comments

En
Python диапазон чисел (python)