迭代器(关键词:Python/iterator/iterable/__iter__/next)

翻译:

迭代器

    我在前面的章节简单地提到过迭代器(iterators)(和可迭代对象(iterables))。在这一节,我深入一些更多的细节。我只涉及一个魔法方法,__iter__,这是迭代器协议的基础。

迭代器协议(protocol)

    进行迭代意味着,重复某些东西几次——就像在循环中做的那样。到现在为止,我在for循环中,只迭代了序列和字典,但是,事实是,你可以对其他对象进行迭代:实现__iter__方法的对象。
    __iter__方法返回一个迭代器,所谓的迭代器,就是具有名叫的next方法的任何对象(next方法是不需要任何参数的callable)。当你调用next方法时,迭代器应该返回它的“下一个值”。如果这个方法被调用,并且迭代器没有更多的值可以返回,就会引发一个StopIteration异常。

注意 迭代器协议在Python3.0中有一点不同。在新的协议中,迭代器对象(iterator objects)应该有一个叫做next的方法,而不是next,并且,一个叫做next的新的内建函数,可以被用来访问这个方法。换句话说,next(it)相当于3.0版本之前的it.next()。

    关键是什么?为什么不只用一个列表?因为列表的杀伤力太大。如果你有一个函数,可以一个接一个地计算值,你可能只需要它们一个接一个——而不是通过列表同时获取所有的值。如果值的数目太大,列表可能占用太多的内存。但是,还有其他的原因:使用迭代器更通用、更简单、更优雅。让我们看一个不使用列表的例子,因为列表会需要无限的长度!
    我们的“列表”是斐波那契序列。一个迭代器如下:
class Fibs:
    def __init__(self):
        self.a = 0
        self.b = 1
    def next(self):
        self.a, self.b = self.b, self.a+self.b
        return self.a
    def __iter__(self):
        return self
注意,迭代器实现了__iter__方法,这个方法实际上返回迭代器自身。在很多情况下,你会把__iter__方法放进另一个对象里,你可以把这个对象用在for循环中。然后,那样会返回你的迭代器。推荐迭代器(iterators)实现一个它们自己的__iter__方法(返回self,就像我在这里做的一样),所以它们自己可以被直接用在for循环中。

    注意  正式的说法是,一个实现了__iter__方法的对象是可迭代对象(iterable),实现了next的对象是迭代器(iterator)。

可迭代对象(iterable)和迭代器(iterator)对比(在Python2中):
这里写图片描述
(上图为译者补充。)
首先,制造一个Fibs对象:

>>> fibs = Fibs()

然后,你可以在一个for循环里使用它(Fibs对象,译者注)——例如,去查找大于1000的最小的斐波那契数:

>>> for f in fibs:
    if f > 1000:
        print f
        break

这里,循环停止了,因为我在它里面设置了break;如果我不这样做,for循环永远不会结束。

>>> it = iter([123])
>>> it.next()
1
>>> it.next()
2

它也可以从一个函数或其他可调用对象(callable)被用来创建一个可迭代对象(iterable)(参见Python库参考, http://docs.python.org/lib/,获取更多细节)。

从迭代器得到序列

    除了在迭代器和可迭代对象中进行迭代(这是你通常所做的),你可以把它们转换成序列。在大多数你可以使用一个序列(除了在索引或者切片的操作中)的上下文中,你可以使用一个迭代器(或一个可迭代对象)替代。关于这个的一个有用的例子是使用list构造器显式地将迭代器转换为列表。
>>> class TestIterator:
    value = 0
    def next(self):
        self.value += 1
        if self.value > 10: raise StopIteration
        return self.value
    def __iter__(self):
        return self
...
>>> ti = TestIteration
>>> list(ti)
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

参考文献:
1.《Beginning Python》2nd Edition 第8章 Iterators
2.《Python基础教程(第2版·修订版)》 9.6 迭代器。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值