Функция
range()
в Python работает с полуоткрытыми интервалами. Например, range(2, 10)
задаёт числа в диапазоне [2, 10)
, то есть [2, 3, 4, 5, 6, 7, 8, 9]
. На первый взгляд это может показаться неочевидным или асимметричным, но у такого подхода есть свои преимущества.Почему полуоткрытые интервалы?
Полуоткрытые интервалы позволяют легко "склеивать" смежные диапазоны без риска ошибок на единицу:
- Если
a = 2
, b = 5
, и c = 10
, то [a, c)
можно выразить как:
[a, c) = [a, b) + [b, c)
Это работает идеально, потому что конец одного интервала (`b`) автоматически становится началом следующего.
В случае закрытых интервалов, такая "склейка" требует дополнительной обработки:
[a, c] = [a, b] + [b+1, c]
Связь с индексацией с нуля
Индексация с нуля в Python также связана с этим принципом. Рассмотрим диапазон
range(0, N)
:- Этот диапазон включает ровно N элементов, что делает код более предсказуемым:
for i in range(0, N):
print(i)
Здесь
i
проходит значения от 0
до N-1
, что логично и удобно.Преимущества для работы с массивами
Полуоткрытые интервалы идеально подходят для работы с индексами массивов:
arr = [10, 20, 30, 40, 50]
print(arr[1:3]) # [20, 30]
Интервал
[1:3)
охватывает элементы с индексами 1
и 2
, но не 3
, что упрощает вычисления границ.Исторический контекст
Этот подход имеет глубокие корни в компьютерной науке. Эдсгер Дейкстра, один из пионеров программирования, в 1982 году написал блестящую статью, в которой обосновал преимущества полуоткрытых интервалов. Это не просто удобство — это вопрос корректности и простоты работы с данными.
👉