Основы Python: работа с числовыми диапазонами

Раздел: Основы Python -> Основы Python: диапазоны

Основы работы с диапазонами чисел

В Python для генерации последовательностей целых чисел применяется встроенная функция range(). Она является основой многих циклов и алгоритмов. Рассмотрим её возможности и различные способы использования.

Функция range(): базовый синтаксис

range(stop) создаёт числа от 0 до stop-1. range(start, stop) задаёт начало и конец (исключительно). range(start, stop, step) определяет шаг. Пример:

for i in range(5):
    print(i, end=' ')
# Вывод: 0 1 2 3 4

for i in range(2, 8):
    print(i, end=' ')
# Вывод: 2 3 4 5 6 7

for i in range(0, 10, 2):
    print(i, end=' ')
# Вывод: 0 2 4 6 8

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

Пояснение: range генерирует числа лениво (итератор) и не хранит их все в памяти. Это эффективно для больших диапазонов.

Типичная ошибка: передача дробных чисел. range() принимает только целые аргументы. Решение: преобразовать значения в int или использовать другой подход, например генератор с while.

Как получить список чисел из диапазона?

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

nums = list(range(0, 10, 2))
print(nums)  # [0, 2, 4, 6, 8]

Примечание: при очень больших диапазонах (например, range(10**7)) такой список займёт много памяти. Лучше работать с итератором напрямую.

Проблема: MemoryError при попытке создать список из огромного range. Решение: не преобразовывать в список без необходимости, использовать range в цикле или срезы.

Как перебрать элементы списка по индексу?

Можно использовать for i in range(len(lst)), но современный стиль рекомендует enumerate().

lst = ['a', 'b', 'c']
for i in range(len(lst)):
    print(i, lst[i])
# 0 a
# 1 b
# 2 c

for i, val in enumerate(lst):
    print(i, val)

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

Как создать убывающий диапазон?

Указать отрицательный шаг. Например, range(10, 0, -1) даст числа от 10 до 1 (исключая 0).

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

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

Как проверить принадлежность числа диапазону без цикла?

Оператор in работает с range: if x in range(0, 100):. Это выполняется за O(1) благодаря математической проверке.

x = 50
if x in range(0, 100):
    print('в диапазоне')
# в диапазоне

Для очень больших чисел проверка остаётся быстрой, но сбивает с толку начинающих, которые ожидают прохода по всем элементам.

Как сгенерировать диапазон с плавающей точкой?

Встроенный range() не поддерживает float. Альтернативы: numpy.arange или собственный генератор.

# Генератор с while
def frange(start, stop, step):
    while start < stop:
        yield start
        start += step

for x in frange(0.0, 1.0, 0.2):
    print(x, end=' ')
# 0.0 0.2 0.4 0.6 0.8

# С использованием numpy
import numpy as np
print(np.arange(0.0, 1.0, 0.2))
# [0.  0.2 0.4 0.6 0.8]

Проблема: numpy не входит в стандартную библиотеку. Для учебных целей подойдёт генератор, однако он накапливает ошибки округления.

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

Отрицательные числа и шаг

Range работает и с отрицательными значениями. Пример: создание чисел от -10 до -1 с шагом 2.

Пример
for i in range(-10, -1, 2):
    print(i, end=' ')
# -10 -8 -6 -4 -2
Результат: -10 -8 -6 -4 -2

Если шаг положительный, а start больше stop, диапазон будет пустым.

Генератор списка на основе range

Range часто используется в list comprehensions для создания последовательностей.

Пример
squares = [x**2 for x in range(10)]
print(squares)
# [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

Range и reversed

Функция reversed() позволяет перебирать числа в обратном порядке без создания списка.

Пример
for i in reversed(range(5)):
    print(i, end=' ')
# 4 3 2 1 0
Результат: 4 3 2 1 0

Параллельный перебор с zip и range

Для одновременного обхода нескольких списков по индексам можно использовать zip(range(len(list1)), list1, list2).

Пример
list1 = ['a','b','c']
list2 = [1,2,3]
for idx, v1, v2 in zip(range(len(list1)), list1, list2):
    print(idx, v1, v2)
# 0 a 1
# 1 b 2
# 2 c 3

Создание двумерного списка (матрицы)

Range вложенных циклов упрощает создание матриц.

Пример
matrix = [[i+j for j in range(3)] for i in range(3)]
print(matrix)
# [[0, 1, 2], [1, 2, 3], [2, 3, 4]]

Range с большим шагом и проверка in

Оператор in работает даже для огромных диапазонов.

Пример
big_range = range(0, 10**9, 1000)
print(500000 in big_range)  # True (проверка за O(1))
print(500001 in big_range)  # False
True
False

Срезы range (range slicing)

Range поддерживает срезы, возвращая новый range-объект. Это удобно для выделения поддиапазонов.

Пример
r = range(0, 10, 1)
sub = r[2:5]  # range(2, 5)
print(list(sub))  # [2, 3, 4]

sub_step = r[1:8:3]  # range(1, 8, 3)
print(list(sub_step))  # [1, 4, 7]
[2, 3, 4]
[1, 4, 7]

Количество элементов в диапазоне

Функция len() возвращает число элементов без их генерации.

Пример
r = range(5, 100, 2)
print(len(r))  # 48
48

Range с itertools.islice для частичного обхода

Пропустить первые N элементов большого диапазона.

Пример
from itertools import islice

big_range = range(10**6)
# Взять первые 10 элементов, начиная с 100
first_ten = list(islice(big_range, 100, 110))
print(first_ten)  # [100, 101, 102, 103, 104, 105, 106, 107, 108, 109]
[100, 101, 102, 103, 104, 105, 106, 107, 108, 109]

Пустой диапазон и его проверка

Пустой диапазон возникает, когда start >= stop при положительном шаге или наоборот при отрицательном.

Пример
if not range(5, 5):
    print('диапазон пуст')
# диапазон пуст

# Также можно проверить длину
print(len(range(10, 5)))  # 0

Диапазоны чисел в Python - comments

En
диапазоны python (python)