我正在研究Alex Marteli's Python in a Nutshell,本书建议任何具有next()
方法的对象(或至少可以用作迭代器)。它还表明大多数迭代器是通过对名为iter
的方法的隐式或显式调用构建的。
在书中读到这篇文章后,我感到有尝试的冲动。我启动了一个python 2.7.3解释器,并做了这个:
>>> x = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> for number in range(0, 10):
... print x.next()
然而结果是:
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
AttributeError: 'list' object has no attribute 'next'
在混乱中,我尝试通过dir(x)
研究x对象的结构,我注意到它有一个__iter__
函数对象。所以我发现它可以用作迭代器,只要它支持那种类型的接口。
所以,当我再次尝试时,这一次略有不同,试图这样做:
>>> _temp_iter = next(x)
我收到了这个错误:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: list object is not an iterator
但是列表怎么可能不是迭代器,因为它似乎支持这个接口,并且当然可以在下面的上下文中用作一个:
>>> for number in x:
... print x
有人可以帮助我在脑海中澄清这一点吗?
答案 0 :(得分:87)
它们是 iterable ,但它们不是迭代器。可以将它们传递给iter()
以隐式地(例如通过for
)或显式地为它们获取迭代器,但它们本身并不是迭代器。
答案 1 :(得分:22)
您需要先使用iter()
将列表转换为迭代器:
In [7]: x = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
In [8]: it=iter(x)
In [9]: for i in range(10):
it.next()
....:
....:
Out[10]: 0
Out[10]: 1
Out[10]: 2
Out[10]: 3
Out[10]: 4
Out[10]: 5
Out[10]: 6
Out[10]: 7
Out[10]: 8
Out[10]: 9
In [12]: 'next' in dir(it)
Out[12]: True
In [13]: 'next' in dir(x)
Out[13]: False
检查对象是否为迭代器:
In [17]: isinstance(x,collections.Iterator)
Out[17]: False
In [18]: isinstance(x,collections.Iterable)
Out[18]: True
In [19]: isinstance(it,collections.Iterable)
Out[19]: True
In [20]: isinstance(it,collections.Iterator)
Out[20]: True
答案 2 :(得分:17)
以防您对iterables和迭代器之间的区别感到困惑。迭代器是表示数据流的对象。它实现了迭代器协议:
__iter__
方法next
方法重复拨打电话 迭代器的next()方法返回流中的连续项。什么时候 没有更多的数据可用迭代器对象耗尽以及任何进一步的调用 next()方法再次提升StopIteration。
另一方面,可迭代对象实现__iter__
方法,该方法在调用时返回迭代器,该方法允许对其数据进行多次传递。可重复使用的对象是可重用的,一旦耗尽,它们就可以重复迭代。可以使用iter
函数将它们转换为迭代器。
因此,如果您有一个列表(可迭代),您可以这样做:
>>> l = [1,2,3,4]
>>> for i in l:
... print i,
1 2 3 4
>>> for i in l:
... print i,
1 2 3 4
如果将列表转换为迭代器:
>>> il = l.__iter__() # equivalent to iter(l)
>>> for i in il:
... print i,
1 2 3 4
>>> for i in il:
... print i,
>>>
答案 3 :(得分:4)
List不是迭代器但是list包含一个迭代器对象__iter__
所以当你尝试在任何列表上使用for循环时,for循环调用__iter__
方法并获取迭代器对象然后它使用next( )列表方法。
x = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
it = x.__iter__()
现在it
包含x
的迭代器对象,您可以将其用作it.next()
,直到抛出StopIteration异常
答案 4 :(得分:0)
关于列表是可迭代但不是迭代器的问题已经有了很好的答案。 在python版本> 3.0,使用以下
a = [1, 2, 3]
b = iter(a)
b.__next__()