← Назад к вопросам

Можно ли обращаться по индексу к 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, все работает автоматически

Можно ли обращаться по индексу к range в Python? | PrepBro