Итератор здесь не создается, итерация не происходит.Объект range
реализован так, что Python вычисляет значение R[5]
по требованию в постоянное время. 1
Если индекс i
не отрицательный, вычисление кипитдо:
i * step + start
Так что в случае вашего кода R[5]
это будет 5*1 + 1
, что равно 6.
Если индекс i
отрицателен, длинаR
сначала добавляется к i
, а затем вычисляется значение, как и раньше:
(i + len(R)) * step + start
Python-internals
Когда вы пишете R[5]
, этоСинтаксис Python в конечном итоге преобразуется в вызов PyObject_GetItem
, который проверяет объект R
, чтобы увидеть, как он должен продолжить поиск элемента по индексу 5.
PyObject_GetItem
первымпроверяет слот tp_as_mapping
типа range
.Это не нуль;он содержит ссылку на структуру с именем range_as_mapping
.PyObject_GetItem
затем проверяет, что находится в mp_subscript
поле этой структуры:
static PyMappingMethods range_as_mapping = {
(lenfunc)range_length, /* mp_length */
(binaryfunc)range_subscript, /* mp_subscript */
(objobjargproc)0, /* mp_ass_subscript */
};
Как видно из приведенного выше фрагмента, он находит range_subscript
функция, занимающая поле mp_subscript
. 2
Теперь range_subscript
проверяет аргументы, которые были переданы (R
и 5
), чтобы решить, является ли одинИндекс или фрагмент был запрошен.Целое число 5
означает, что необходим только один индекс, и поэтому функция делегирует вычисление значения compute_range_item
.Эта функция выполняет вычисление для возврата целого числа 6, как указано в первой части этого ответа.
1 Я предполагаю, что вы используете CPython: другие реализации Python могут реализовыватьrange
объект по-разному.
2 Если вы должны были вызвать len(R)
, вы можете увидеть внутреннюю функцию в mp_length
, которая вызывается для вычисления длины R
(см. Почему «1000000000000000 в диапазоне (1000000000000001)» так быстро в Python 3? ).