Подтвердить что ты не робот

Если range() является генератором в Python 3.3, почему я не могу вызвать next() в диапазоне?

Возможно, я стал жертвой дезинформации в Интернете, но я думаю, что это скорее всего, что я что-то не понял. Основываясь на том, что я узнал до сих пор, range() является генератором, а генераторы могут использоваться как итераторы. Однако этот код:

myrange = range(10)
print(next(myrange))

дает мне эту ошибку:

TypeError: 'range' object is not an iterator

Что мне здесь не хватает? Я ожидал, что это напечатает 0 и перейти к следующему значению в myrange. Я новичок в Python, поэтому, пожалуйста, примите мои извинения за довольно простой вопрос, но я не мог найти хорошее объяснение нигде.

4b9b3361

Ответ 1

range - это класс неизменяемых итерируемых объектов. Их итерационное поведение можно сравнить с list s: вы не можете называть next непосредственно на них; вам нужно получить итератор, используя iter.

Итак, нет, range не является генератором.

Возможно, вы думаете: "Почему они не сделали это прямое итерабельным"? Ну, range имеют некоторые полезные свойства, которые были бы невозможны таким образом:

  • Они неизменяемы, поэтому их можно использовать в качестве словарных клавиш.
  • У них есть атрибуты start, stop и step (начиная с методов Python 3.3), count и index, и они поддерживают операции in, len и __getitem__.
  • Вы можете перебирать один и тот же range несколько раз.

>>> myrange = range(1, 21, 2)
>>> myrange.start
1
>>> myrange.step
2
>>> myrange.index(17)
8
>>> myrange.index(18)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: 18 is not in range
>>> it = iter(myrange)
>>> it
<range_iterator object at 0x7f504a9be960>
>>> next(it)
1
>>> next(it)
3
>>> next(it)
5