简体   繁体   English

与python列表混淆:它们还是不是迭代器?

[英]Confused with python lists: are they or are they not iterators?

I am studying Alex Marteli's Python in a Nutshell and the book suggests that any object that has a next() method is (or at least can be used as) an iterator . 在一个Nutshell中研究Alex Marteli的Python,书中建议任何具有next()方法的对象(或者至少可以用作迭代器) It also suggests that most iterators are built by implicit or explicit calls to a method called iter . 它还表明大多数迭代器是通过对名为iter的方法的隐式或显式调用构建的。

After reading this in the book, I felt the urge to try it. 在书中读到这篇文章后,我感受到了尝试它的冲动。 I fired up a python 2.7.3 interpreter and did this: 我启动了一个python 2.7.3解释器,并做到了这一点:

>>> x = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> for number in range(0, 10):
...     print x.next()

However the result was this: 但结果如下:

Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
AttributeError: 'list' object has no attribute 'next'

In confusion, I tried to study the structure of the x object via dir(x) and I noticed that it had a __iter__ function object. 在混乱中,我试图通过dir(x)研究x对象的结构,我注意到它有一个__iter__函数对象。 So I figured out that it can be used as an iterator, so long as it supports that type of interface. 所以我发现它可以用作迭代器,只要它支持那种类型的接口。

So when I tried again, this time slightly differently, attempting to do this: 所以当我再次尝试时,这一次略有不同,尝试这样做:

>>> _temp_iter = next(x)

I got this error: 我收到了这个错误:

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

But how can a list NOT be an iterator, since it appears to support this interface, and can be certainly used as one in the following context: 但是如何列表不是迭代器,因为它似乎支持这个接口,并且当然可以在以下上下文中用作一个:

>>> for number in x:
...     print x

Could someone help me clarify this in my mind? 有人可以帮助我在脑海中澄清这一点吗?

They are iterable , but they are not iterators . 它们是可迭代的 ,但它们不是迭代器 They can be passed to iter() to get an iterator for them either implicitly (eg via for ) or explicitly, but they are not iterators in and of themselves. 它们可以传递给iter()以隐式(例如,通过for )或显式地为它们获取迭代器,但它们本身并不是迭代器。

You need to convert list to an iterator first using iter() : 您需要首先使用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

checking whether an object is iterator or not: 检查对象是否是迭代器:

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

Just in case you are confused about what the difference between iterables and iterators is. 以防您对iterables和迭代器之间的区别感到困惑。 An iterator is an object representing a stream of data. 迭代器是表示数据流的对象。 It implements the iterator protocol: 它实现了迭代器协议:

  • __iter__ method __iter__方法
  • next method next方法

Repeated calls to the iterator's next() method return successive items in the stream. 重复调用迭代器的next()方法返回流中的连续项。 When no more data is available the iterator object is exhausted and any further calls to its next() method just raise StopIteration again. 当没有更多数据可用时,迭代器对象就会耗尽,并且对next()方法的任何进一步调用都会再次引发StopIteration。

On the other side iterable objects implement the __iter__ method that when called returns an iterator, which allows for multiple passes over their data. 另一方面,可迭代对象实现__iter__方法,该方法在调用时返回迭代器,该迭代器允许对其数据进行多次传递。 Iterable objects are reusable, once exhausted they can be iterated over again. 可重复使用的对象是可重用的,一旦耗尽,它们就可以重复迭代。 They can be converted to iterators using the iter function. 可以使用iter函数将它们转换为迭代器。

So if you have a list (iterable) you can do: 所以,如果你有一个列表(可迭代),你可以这样做:

>>> 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

If you convert your list into an iterator: 如果将列表转换为迭代器:

>>> il = l.__iter__()  # equivalent to iter(l)
>>> for i in il:
...     print i,
 1 2 3 4
>>> for i in il:
...     print i,
>>> 

List is not iterator but list contains an iterator object __iter__ so when you try to use for loop on any list, for loop calls __iter__ method and gets the iterator object and then it uses next() method of list. List不是迭代器,但是list包含一个迭代器对象__iter__所以当你尝试在任何列表中使用for循环时,for循环调用__iter__方法并获取迭代器对象然后它使用list的next()方法。

x = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
it = x.__iter__()

Now it contains iterator object of x which you can use as it.next() until StopIteration exception is thrown 现在it包含x迭代器对象,您可以将其用作it.next()直到抛出StopIteration异常

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM