Функция range в Python: создание числовых последовательностей
Работа с 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 помогает в динамическом формировании индексов.