← Назад к вопросам
Можно ли обращаться по индексу к range в Python?
1.0 Junior🔥 121 комментариев
#Python Core
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Доступ по индексу к range в Python
Прямой ответ: ДА, можно.
range в Python 3 поддерживает индексирование.
Примеры
# ✓ Это работает
r = range(10) # 0, 1, 2, ..., 9
print(r[0]) # 0
print(r[5]) # 5
print(r[-1]) # 9
print(r[2:5]) # range(2, 5) -> 2, 3, 4
# С параметрами
r = range(5, 15, 2) # 5, 7, 9, 11, 13
print(r[0]) # 5
print(r[2]) # 9
print(r[-1]) # 13
print(r[1:3]) # range(7, 11, 2) -> 7, 9
Как это работает
r = range(10)
# range - это immutable sequence type
# Поддерживает протокол sequence:
print(len(r)) # 10
print(5 in r) # True
print(11 in r) # False
print(list(r)) # [0, 1, 2, ..., 9]
print(r == range(10)) # True
# Слайсирование работает
print(r[2:5]) # range(2, 5)
print(r[::2]) # range(0, 10, 2) -> 0, 2, 4, 6, 8
print(r[::-1]) # range(9, -1, -1) -> 9, 8, 7, ..., 0
Почему это работает
# range - это класс, который реализует __getitem__
class MyRange:
def __init__(self, start, stop=None, step=1):
if stop is None:
self.start = 0
self.stop = start
else:
self.start = start
self.stop = stop
self.step = step
def __getitem__(self, index):
# Это позволяет индексирование
if isinstance(index, slice):
# Обработать slice
pass
else:
# Обработать int индекс
return self.start + index * self.step
def __len__(self):
return max(0, (self.stop - self.start + self.step - 1) // self.step)
# Поэтому range[5] работает
Производительность
# ✓ Эффективно - O(1)
r = range(1000000)
print(r[999999]) # Мгновенно
# В отличие от list
lst = list(range(1000000))
print(lst[999999]) # Тоже быстро, но использует больше памяти
# range не создает список в памяти
import sys
print(sys.getsizeof(range(1000000))) # ~48 байт
print(sys.getsizeof(list(range(1000)))) # ~9000+ байт
Практические примеры
# Получить каждый n-й элемент
r = range(100)
print(r[::10]) # range(0, 100, 10) -> 0, 10, 20, ..., 90
# Реверс
r = range(10)
print(r[::-1]) # range(9, -1, -1) -> 9, 8, ..., 0
# Slice
r = range(100)
print(r[10:20]) # range(10, 20)
print(r[10:50:5]) # range(10, 50, 5)
# Проверить диапазон
r = range(5, 15)
print(0 in r) # False
print(10 in r) # True
# Итерирование из середины
r = range(100)
for i in r[50:]:
print(i) # 50, 51, 52, ..., 99
Сравнение с list
# range
r = range(100)
print(r[50]) # O(1) - вычисляется
slice_r = r[10:20] # O(1) - новый range объект
# list
lst = list(range(100))
print(lst[50]) # O(1) - доступ
slice_lst = lst[10:20] # O(n) - копирует элементы
# Вывод: range более эффективен для больших диапазонов
Когда использовать
# ✓ Используй range[index] когда:
# - Нужен элемент из range
# - Есть срез range-а
# - Хочешь проверить наличие элемента
# ✓ Но если часто используешь индексирование
if need_many_indices:
# Конвертируй в list один раз
lst = list(range(1000000))
for i in lst:
process(i)
# ❌ Не нужно делать так:
for i in range(len(data)):
# Если просто нужны значения
print(i)
# ✓ Делай так:
for i in range(len(data)):
# Если нужен индекс для доступа к другому списку
print(data[i])
Вывод
Можно ли обращаться по индексу к range?
ДА! ✓
r = range(10)
print(r[5]) # 5
print(r[2:5]) # range(2, 5)
print(r[-1]) # 9
print(r[::2]) # range(0, 10, 2)
Почему это работает?
range реализует протокол sequence (__getitem__, __len__)
Это эффективно? ДА! O(1) операция, не требует доступа к памяти
Когда использовать? Когда нужен элемент из range, все работает автоматически