为什么范围对象"不是迭代器"?

tem*_*ame 21 python generator python-3.x

我写了这个并且期望0:

>>> x = range(20)
>>> next(x)
Run Code Online (Sandbox Code Playgroud)

相反,我得到了:

TypeError:'range'对象不是迭代器

但我以为这是一个发电机?

最初的答案产生了我最初对自己说的同样的事情:它是一个可迭代的,而不是一个交互者.但是,如果两者都是简单的生成器,那么这就无法解释为什么会这样做:

>>> x = (i for i in range(30))
>>> next(x)
0
Run Code Online (Sandbox Code Playgroud)

NPE*_*NPE 18

范围对象是可迭代的.但是,它不是一个迭代器.

要获得迭代器,您需要先调用iter():

>>> r=range(5,15)
>>> next(iter(r))
5
>>> next(iter(r))
5
>>> next(iter(r))
5
>>> next(iter(r))
5
>>> i=iter(r)
>>> next(i)
5
>>> next(i)
6
>>> next(i)
7
>>> next(i)
8
>>> iter(r)
<range_iterator object at 0x10b0f0630>
>>> iter(r)
<range_iterator object at 0x10b0f0750>
>>> iter(r)
<range_iterator object at 0x10b0f0c30>
Run Code Online (Sandbox Code Playgroud)

编辑:但要注意不要拨打iter()电话next().它在索引0处创建一个新的迭代器.


Mik*_*ham 9

range返回一个可迭代的,而不是一个迭代器.它可以在需要迭代时生成迭代器.它不是发电机.

生成器表达式求值为迭代器(因此也是迭代器).

  • 请注意,您可以通过调用 iter() 来从这个可迭代对象中获取一个迭代器。然后,您可以对 iter(range(...)) 的结果调用 next() 内置函数。这很令人困惑,但这只是当您深入了解该语言时学到的东西之一。请注意,for 循环隐式调用 iter(expression) 一次,然后每次通过循环时都调用 next(results_from_iter)。 (2认同)

mgi*_*son 5

next内置调用__next__挂钩方法。所以,range对象有一个明确定义的__iter__,但没有一个明确定义的__next__

可迭代对象已__iter__定义,迭代器对象已明确定义__next__(通常使用__iter__简单返回的方法self)。