2017-08-02 214 views
4

我已经阅读了我的资料,它告诉python迭代器必须同时有__iter____next__方法,但是迭代只需要__iter__。我检查一个清单,发现它没有__next__方法。当使用iter()时,它将成为迭代器。这意味着iter()会将__next__方法添加到列表中以将其转换为迭代器?如果是的话,这是怎么发生的?内置函数iter()如何将python列表转换为迭代器?

+1

尼斯摘要:http://nvie.com/posts/iterators-vs-generators/ – mkrieger1

回答

4

iter返回迭代器,它不会将列表转换为迭代器。它根本不修改列表,当然,该列表没有得到__next__方法。

>>> x = [1,2] 
>>> it = iter(x) 
>>> it 
<list_iterator object at 0x101c021d0> 
>>> x.__next__ 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
AttributeError: 'list' object has no attribute '__next__' 
>>> 

列表是iterables,不迭代器。他们实现一个__iter__方法,因此它们是可迭代:

>>> x.__iter__ 
<method-wrapper '__iter__' of list object at 0x101bcf248> 

但不是__next__,因此,他们不是迭代器:

>>> next(x) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
TypeError: 'list' object is not an iterator 

迭代器本身是可迭代的,顾名思义,因为他们实施__iter__为好。试想一下:

>>> x = [1, 2, 3, 4, 5, 6, 7, 8, 9] 
>>> it = iter(x) 
>>> it 
<list_iterator object at 0x101c02358> 
>>> it.__iter__ 
<method-wrapper '__iter__' of list_iterator object at 0x101c02358> 

大多数 迭代器,当你对他们使用iter应该简单地返回自己:

>>> it2 = iter(it) 
>>> it, it2 
(<list_iterator object at 0x101c02358>, <list_iterator object at 0x101c02358>) 
>>> it is it2 
True 
>>> 

事实上,这是一个requirement of the iterator protocol:需要

”迭代器有一个__iter__()方法返回 iter ator对象本身,所以每个迭代器也是可迭代的,并且可能在其他迭代器被接受的大多数地方使用 。

注意,同样,他们是相同的迭代器

>>> next(it) 
1 
>>> next(it2) 
2 
>>> next(it) 
3 
>>> next(it) 
4 
>>> next(it2) 
5 
>>> list(it) 
[6, 7, 8, 9] 
>>> next(it2) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
StopIteration 

因此,一个迭代实现__iter____next__,一个迭代只是意味着它实现__iter__。什么是返回__iter__是一个迭代器,所以必须执行__next__

+0

关键是,'__next__'方法是_on thing_ iter'返回 – Eevee

+0

注意:*所有*迭代器必须有一个' __iter__'实现返回迭代器对象本身,而不仅仅是“最”。这是[迭代器协议的要求](https://docs.python.org/3/glossary.html#term-iterator):“迭代器需要有一个返回迭代器对象的__iter __()方法,因此每个迭代器也是可迭代的,并且可以在其他迭代器被接受的大多数地方使用。“Python的其他部分依赖于此;一种规范而有效的鸭式打印方法来测试某些东西是否为迭代器就是测试'obj is iter iter(someobj)'。 – ShadowRanger

+0

@ShadowRanger是的,你是绝对正确的。没有什么能阻止你打破这个,但我当然不会建议这样做,我会更新以反映这一点。 –

相关问题