python 内置函数 iter() 如何将 python 列表转换为迭代器?

shu*_*qin 5 python iterator iterable

我已经阅读了我的材料,它告诉我 python 迭代器必须同时具有__iter____next__方法,但可迭代只需要__iter__. 我检查了一个列表,发现它没有__next__方法。当iter()在其上使用时,它将成为一个迭代器。这意味着iter()将向__next__列表添加一个方法以将其转换为迭代器?如果是,这是如何发生的?

jua*_*aga 6

不。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__'
>>>
Run Code Online (Sandbox Code Playgroud)

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

>>> x.__iter__
<method-wrapper '__iter__' of list object at 0x101bcf248>
Run Code Online (Sandbox Code Playgroud)

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

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

根据定义,迭代器本身是可迭代的,因为它们也实现__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>
Run Code Online (Sandbox Code Playgroud)

大多数迭代器在你使用它们时应该简单地返回自己iter

>>> it2 = iter(it)
>>> it, it2
(<list_iterator object at 0x101c02358>, <list_iterator object at 0x101c02358>)
>>> it is it2
True
>>>
Run Code Online (Sandbox Code Playgroud)

事实上,这是迭代器协议要求

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

再次注意,它们是相同的迭代器

>>> 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
Run Code Online (Sandbox Code Playgroud)

所以迭代器实现了__iter__and __next__,一个迭代器仅仅意味着它实现了__iter__。什么是返回__iter__是一个迭代器,这样就必须执行__next__