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

Python 为什么范围对象是;不是迭代器;?,python,python-3.x,generator,Python,Python 3.x,Generator,我写了这个,希望0: >>> x = range(20) >>> next(x) 相反,我得到了: TypeError:“范围”对象不是迭代器 但我还以为是发电机呢 最初的答案和我最初对自己说的一样:它是一个可移植的,而不是一个互动器。但是,如果两者都只是发电机,这并不能解释为什么这样做有效: >>> x = (i for i in range(30)) >>> next(x) 0 范围对象是可编辑的。但是,它不是迭代器

我写了这个,希望
0

>>> x = range(20)
>>> next(x)
相反,我得到了:

TypeError:“范围”对象不是迭代器

但我还以为是发电机呢

最初的答案和我最初对自己说的一样:它是一个可移植的,而不是一个互动器。但是,如果两者都只是发电机,这并不能解释为什么这样做有效:

>>> x = (i for i in range(30))
>>> next(x)
0
范围对象是可编辑的。但是,它不是迭代器

要获取迭代器,需要首先调用:

>r=范围(5,15)
>>>下一步(国际热核实验堆(r))
5.
>>>下一步(国际热核实验堆(r))
5.
>>>下一步(国际热核实验堆(r))
5.
>>>下一步(国际热核实验堆(r))
5.
>>>i=国际热核实验堆(iter)
>>>下一(i)
5.
>>>下一(i)
6.
>>>下一(i)
7.
>>>下一(i)
8.
>>>国际热核实验堆(iter)
>>>国际热核实验堆(iter)
>>>国际热核实验堆(iter)

编辑:但注意不要每次调用
next()
都调用
iter()
。它在索引0处创建一个新的迭代器。

范围
返回一个iterable,而不是迭代器。它可以在需要迭代时生成迭代器它不是发电机。


生成器表达式的计算结果为迭代器(因此也是iterable)。

这是因为
next
函数调用传入对象的
next
方法

next(...)
    x.next() -> the next value, or raise StopIteration
listiterator
s和
generator
s都有
next
方法

>>> iter(range(1)).__class__.next
<slot wrapper 'next' of 'listiterator' objects>
>>> iter(x for x in range(1)).__class__.next
<slot wrapper 'next' of 'generator' objects>
next
不太关心它传递的对象是否是迭代器

>>> class Foo():
...     def next(self):
...             return "foo"
... 
>>> foo = Foo()
>>> next(foo)
'foo'
>>> next(foo)
'foo'
但是添加
next
方法并不一定使它成为一个集合/序列/iterable

>>> class Foo():
...     def next(self):
...             return "Foo"
>>> [x for x in Foo()]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: iteration over non-sequence
>>> iter(Foo())
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: iteration over non-sequence
当涉及到
列表时,下一个
似乎有一些内置的智能

>>> class Foo():
...     pass
... 
>>> foo = Foo()
>>> next(foo)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: instance has no next() method
>>> next(range(20))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: list object is not an iterator
>类Foo():
...     通过
... 
>>>foo=foo()
>>>下一个(foo)
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
TypeError:实例没有next()方法
>>>下一个(范围(20))
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
TypeError:列表对象不是迭代器

内置的
next
调用
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
钩子方法。因此,
范围
对象有一个定义良好的
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
,但没有一个定义良好的<


iterable对象已经定义了
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
方法,迭代器对象已经定义了
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu。但是,为什么这样做呢:
下一步((范围(30)中的i代表i))
,因为这是一个生成器表达式?事实上,让我将此添加到问题中。“它确实是一个生成器”-不,不是。@Aerovista:因为生成器表达式的计算结果是迭代器?@NPE tldr;生成器可以被视为迭代器,正如我所想。因此,这些信息是不相关的——正确答案是range()对象是不可变的、特殊的,事实上不是简单的生成器。@user2357112:哦,我没有调用它。这就解释了。漫长的一天,我要睡觉了。
iterable!=迭代器
也相关:请注意,通过调用iter()可以从这个iterable中得到迭代器。然后,可以调用iter(范围)结果的next()内置项(…)。这很让人困惑,但这只是当你深入研究该语言时所学到的东西之一。请注意,for循环隐式调用iter(表达式)一次,然后再调用下一次(来自iter的结果)。
>>> class Foo():
...     def next(self):
...             return "Foo"
>>> [x for x in Foo()]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: iteration over non-sequence
>>> iter(Foo())
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: iteration over non-sequence
>>> class Foo():
...     def next(self):
...             return "Foo"
...     def __iter__(self): return self
... 
>>> [x for x in Foo()]
^CTraceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyboardInterrupt
>>> iter(Foo())
<__main__.Foo instance at 0x7fd77307c488>
>>> class Foo():
...     pass
... 
>>> foo = Foo()
>>> next(foo)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: instance has no next() method
>>> next(range(20))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: list object is not an iterator