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