Python中的“iterable”、“iterator”和“iteration”是什么?它们是如何定义的?


当前回答

以下是我在教授Python课程时使用的解释:

ITERABLE是:

任何可以循环的东西(例如,你可以循环一个字符串或文件)或 任何可以出现在for循环右边的东西:for x in iterable:…或 任何你可以用iter()调用并返回ITERATOR: iter(obj)或 一个定义__iter__的对象,该对象返回一个新的ITERATOR, 或者它可能有一个适合索引查找的__getitem__方法。

ITERATOR是一个对象:

在迭代过程中,state会记住它的位置, 使用__next__方法: 返回迭代中的下一个值 更新状态以指向下一个值 信号,当它完成时,引发StopIteration 并且它是可自迭代的(意味着它有一个返回self的__iter__方法)。

注:

Python 3中的__next__方法在Python 2中拼写为next,并且 内置函数next()在传递给它的对象上调用该方法。

例如:

>>> s = 'cat'      # s is an ITERABLE
                   # s is a str object that is immutable
                   # s has no state
                   # s has a __getitem__() method 

>>> t = iter(s)    # t is an ITERATOR
                   # t has state (it starts by pointing at the "c"
                   # t has a next() method and an __iter__() method

>>> next(t)        # the next() function returns the next value and advances the state
'c'
>>> next(t)        # the next() function returns the next value and advances
'a'
>>> next(t)        # the next() function returns the next value and advances
't'
>>> next(t)        # next() raises StopIteration to signal that iteration is complete
Traceback (most recent call last):
...
StopIteration

>>> iter(t) is t   # the iterator is self-iterable

其他回答

对我来说,Python的glossery对这些问题最有帮助,例如对于iterable,它说:

每次能够返回一个成员的对象。可迭代对象的例子包括所有序列类型(如list、str和tuple)和一些非序列类型,如dict、文件对象,以及使用iter()方法或使用实现sequence语义的getitem()方法定义的任何类的对象。

Iterables can be used in a for loop and in many other places where a sequence is needed (zip(), map(), …). When an iterable object is passed as an argument to the built-in function iter(), it returns an iterator for the object. This iterator is good for one pass over the set of values. When using iterables, it is usually not necessary to call iter() or deal with iterator objects yourself. The for statement does that automatically for you, creating a temporary unnamed variable to hold the iterator for the duration of the loop. See also iterator, sequence, and generator.

这是另一个使用collections.abc的视图。这个视图在第二次或以后可能会有用。

从集合。ABC我们可以看到下面的层次结构:

builtins.object
    Iterable
        Iterator
            Generator

例如,Generator是由Iterator派生的Iterable是由基对象派生的。

因此,

Every iterator is an iterable, but not every iterable is an iterator. For example, [1, 2, 3] and range(10) are iterables, but not iterators. x = iter([1, 2, 3]) is an iterator and an iterable. A similar relationship exists between Iterator and Generator. Calling iter() on an iterator or a generator returns itself. Thus, if it is an iterator, then iter(it) is it is True. Under the hood, a list comprehension like [2 * x for x in nums] or a for loop like for x in nums:, acts as though iter() is called on the iterable (nums) and then iterates over nums using that iterator. Hence, all of the following are functionally equivalent (with, say, nums=[1, 2, 3]): for x in nums: for x in iter(nums): for x in iter(iter(nums)): for x in iter(iter(iter(iter(iter(nums))))):

迭代对象有一个__iter__方法,每次都会实例化一个新的迭代器。 迭代器实现了一个__next__方法返回单个项,以及一个__iter__方法返回self。 因此,迭代器也是可迭代的,但可迭代的不是迭代器。

卢西亚诺·拉马略,流利的蟒蛇。

iterable = [1, 2] 

iterator = iter(iterable)

print(iterator.__next__())   

print(iterator.__next__())   

so,

Iterable是一个可以循环的对象。例如,列表,字符串,元组等。 在iterable对象上使用iter函数将返回一个迭代器对象。 现在这个迭代器对象有一个名为__next__的方法(在Python 3中,或者在Python 2中只是next),通过它你可以访问iterable的每个元素。

所以, 以上代码的输出为:

1

2

我不知道这是否对任何人都有帮助,但我总是喜欢在脑子里把概念形象化,以便更好地理解它们。所以,就像我有一个小儿子一样,我用砖块和白纸来想象迭代器/迭代器的概念。

Suppose we are in the dark room and on the floor we have bricks for my son. Bricks of different size, color, does not matter now. Suppose we have 5 bricks like those. Those 5 bricks can be described as an object – let’s say bricks kit. We can do many things with this bricks kit – can take one and then take second and then third, can change places of bricks, put first brick above the second. We can do many sorts of things with those. Therefore this bricks kit is an iterable object or sequence as we can go through each brick and do something with it. We can only do it like my little son – we can play with one brick at a time. So again I imagine myself this bricks kit to be an iterable.

现在请记住,我们是在一个黑暗的房间里。或者几乎是黑暗的。问题是我们看不清这些砖,它们是什么颜色,什么形状等等。所以即使我们想对它们做些什么——也就是迭代它们——我们也不知道要做什么,怎么做,因为太暗了。

我们能做的是靠近第一块砖-作为一个砖套件的元素-我们可以放一张白色荧光纸,以便我们看到第一块砖元素在哪里。每次我们从工具箱中取出一块砖,我们就把这张白纸换成下一块砖,这样就能在黑暗的房间里看到它。这张白纸只不过是一个迭代器。它也是一个对象。而是一个我们可以使用可迭代对象中的元素的对象——bricks工具包。

顺便说一下,这解释了我早期的错误,当我在IDLE中尝试以下操作时,得到了一个TypeError:

 >>> X = [1,2,3,4,5]
 >>> next(X)
 Traceback (most recent call last):
    File "<pyshell#19>", line 1, in <module>
      next(X)
 TypeError: 'list' object is not an iterator

这里的列表X是我们的砖块工具包,但不是一张白纸。我需要先找到一个迭代器:

>>> X = [1,2,3,4,5]
>>> bricks_kit = [1,2,3,4,5]
>>> white_piece_of_paper = iter(bricks_kit)
>>> next(white_piece_of_paper)
1
>>> next(white_piece_of_paper)
2
>>>

不知道有没有帮助,但对我有帮助。如果有人能确认/纠正这个概念的可视化,我会很感激。这会帮助我了解更多。