If range() is a generator in Python 3.3, why can I not call next() on a range?

也许我已经成为网络上错误信息的受害者,但我认为更有可能的是我误解了某些东西。基于我到目前为止学到的知识,range ()是一个生成器,生成器可以用作迭代器。但是,这个代码:

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

给了我这个错误:

TypeError: 'range' object is not an iterator

我错过了什么?我期望它输出0,然后前进到 myrange中的下一个值。我是 Python 的新手,所以请接受我对这个相当基本的问题的道歉,但是我在其他地方找不到一个好的解释。

37042 次浏览

range是一类不可变的可迭代对象。它们的迭代行为可以与 list进行比较: 您不能直接对它们调用 next; 您必须通过使用 iter获得迭代器。

所以 range不是发电机。

你可能会想,“为什么他们不把它变成迭代器呢?”?range有一些有用的属性,这是不可能的:

  • 它们是不可变的,因此可以用作字典键。
  • 它们具有 startstopstep属性(自 Python 3.3以来)、 countindex方法,并且支持 inlen__getitem__操作。
  • You can iterate over the same range multiple times.

>>> 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