首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >迭代器、可迭代和迭代到底是什么?

迭代器、可迭代和迭代到底是什么?
EN

Stack Overflow用户
提问于 2012-03-27 14:03:38
回答 17查看 364.7K关注 0票数 508

Python中"iterable“、"iterator”和"iteration“的最基本定义是什么?

我读过很多种定义,但我不能确定它的确切含义,因为它仍然不能被理解。

有没有人能帮我用外行术语解释一下这3个定义?

EN

回答 17

Stack Overflow用户

回答已采纳

发布于 2012-03-27 14:15:50

Iteration是一个通用术语,用于一个接一个地获取某物的每一项。任何时候你使用一个循环,显式的或隐式的,遍历一组项目,那就是迭代。

在Python语言中,迭代器迭代器有特定的含义。

可迭代是具有__iter__方法的对象,该方法返回迭代器,或者定义__getitem__方法,该方法可以采用从零开始的连续索引(并在索引不再有效时引发IndexError )。因此,可迭代是一个可以从中获取迭代器的对象。

迭代器是具有next (Python2)或__next__ (Python3)方法的对象。

无论何时在Python语言中使用for循环、map或列表理解等,都会自动调用next方法以从迭代器中获取每一项,从而经历迭代的过程。

iterators section of the tutorialiterator types section of the standard types page开始学习是个不错的选择。在理解了基础知识之后,尝试使用iterators section of the Functional Programming HOWTO

票数 588
EN

Stack Overflow用户

发布于 2012-03-27 14:39:31

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

一种可能性是:

  • 任何可以循环的内容(即,您可以循环字符串或文件)或
  • 任何可以出现在for循环右侧的内容:for x in iterable: ...
  • 任何可以用iter()调用并返回ITERATOR的对象:iter(obj)
  • 定义返回新ITERATOR的__iter__的对象,或者它可能具有适合索引查找的__getitem__方法。

ITERATOR是一个对象:

具有记住其在迭代期间所处位置的状态的

  • ,具有通过引发StopIteration

而完成时将指向下一个iteration

  • updates的状态的
  • 返回状态中的下一个值的

  • ,也就是self-iterable (表示它有一个返回self).

__iter__方法

备注:

  • Python3中的__next__方法在Python2中拼写为next
  • 内置函数next()在传递给它的对象上调用该方法。

例如:

代码语言:javascript
复制
>>> 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
票数 378
EN

Stack Overflow用户

发布于 2013-09-11 22:59:39

上面的答案很棒,但就我所见的大多数情况而言,对于像我这样的人来说,不要强调它们的区别。

此外,人们倾向于通过在前面添加"X是一个具有__foo__()方法的对象“之类的定义来变得”过于Pythonic“。这样的定义是正确的--它们基于鸭子类型的哲学,但在试图理解概念的简单性时,对方法的关注往往会介于两者之间。

所以我添加了我的版本。

在自然语言中

  • iteration是一次获取一行元素中的一个元素的过程。

在Python中,

  • iterable是一个可迭代的对象,简单地说,这意味着它可以在迭代中使用,例如与for循环一起使用。多么?通过使用迭代器。我会在下面解释。
  • ..。而迭代器是一个定义如何实际进行迭代的对象--特别是定义下一个元素是什么。这就是为什么它必须有next()方法。

迭代器本身也是可迭代的,区别在于它们的__iter__()方法返回相同的对象(self),而不管它的项是否已被先前对next()的调用所使用。

那么,当Python解释器看到for x in obj:语句时会怎么想呢?

看,一个for循环。看起来像是迭代器的工作...我们去买一个吧。..。有个叫obj的,我们去问问他吧。

obj先生,你有你的迭代器吗?”调用iter(obj),后者调用obj.__iter__(),后者很乐意提供一个闪亮的新迭代器_i。)

好的,这很简单……那么让我们开始迭代吧。(x = _i.next() ... x = _i.next()...)

由于obj先生在这个测试中成功了(通过让某些方法返回一个有效的迭代器),我们用形容词奖励他:您现在可以称他为“可迭代的obj先生”。

然而,在简单的情况下,通常不会从分别使用iterator和iterable中受益。所以您只定义了一个对象,它也是它自己的迭代器。( obj提供的_i并不那么闪亮,Python并不关心这一点,只是关心obj本身。)

这就是为什么在我见过的大多数示例中(以及让我一次又一次感到困惑的是什么),你可以看到:

代码语言:javascript
复制
class IterableExample(object):

    def __iter__(self):
        return self

    def next(self):
        pass

而不是

代码语言:javascript
复制
class Iterator(object):
    def next(self):
        pass

class Iterable(object):
    def __iter__(self):
        return Iterator()

然而,在某些情况下,您可以从迭代器和迭代器分离中受益,例如当您想要有一行项目,但有更多的“游标”时。例如,当你想要处理“当前”和“即将到来”的元素时,你可以对这两个元素分别使用不同的迭代器。或者从一个巨大的列表中提取多个线程:每个线程都可以有自己的迭代器来遍历所有项。请参阅上面的@Raymond's@glglgl's答案。

想象一下你可以做什么:

代码语言:javascript
复制
class SmartIterableExample(object):

    def create_iterator(self):
        # An amazingly powerful yet simple way to create arbitrary
        # iterator, utilizing object state (or not, if you are fan
        # of functional), magic and nuclear waste--no kittens hurt.
        pass    # don't forget to add the next() method

    def __iter__(self):
        return self.create_iterator()

备注:

我再重复一遍:

  • 是不可迭代的。迭代器不能用作for循环中的“源”。for循环主要需要的是__iter__() (它用(while...).
  • Iterator's for返回一些东西,__iter__()不是唯一的迭代循环,所以上面也适用于其他一些构造),(while...).
  • Iterator‘s next()可以抛出StopIteration来停止迭代。
  • 在上面的“思考过程”中,_i并不真正存在。我已经创建了Python3.x中的一个小更改:next()方法(不是内置的)现在必须称为__next__()。是的,它应该一直都是这样的,你也可以这样想:
  • 有数据,迭代器拉出下一项

免责声明:我不是任何Python解释器的开发者,所以我真的不知道解释器是怎么想的。上面的思考只是演示了我是如何从Python新手的其他解释、实验和现实生活经验中理解这个主题的。

票数 112
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9884132

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档