Python基础教程 迭代器协议

9.6 迭代器

本书前面粗略地提及了迭代器(和可迭代对象),本节将更详细地介绍。对于魔法方法,这里只介绍__iter__,它是迭代器协议的基础。

9.6.1 迭代器协议

迭代(iterate)意味着重复多次,就像循环那样。本书前面只使用for循环迭代过序列和字典,但实际上也可迭代其他对象:实现了方法__iter__的对象。

方法__iter__返回一个迭代器,它是包含方法__next__的对象,而调用这个方法时可不提供任何参数。当你调用方法__next__时,迭代器应返回其下一个值。如果迭代器没有可供返回的值,应引发StopIteration异常。你还可使用内置的便利函数next,在这种情况下, next(it)与it.__next__()等效。

注意 在Python 3中,迭代器协议有细微的变化。在以前的迭代器协议中,要求迭代器对象包含方法next而不是__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循环中使用这个对象。但推荐在迭代器中也实现方法__iter__(并像刚才那样让它返回self),这样迭代器就可直接用于for循环中。

注意 更正规的定义是,实现了方法__iter__的对象是可迭代的,而实现了方法__next__的对象是迭代器。

首先,创建一个Fibs对象。

>>> fibs = Fibs()

然后就可在for循环中使用这个对象,如找出第一个大于1000的斐波那契数。

>>> for f in fibs:

... if f > 1000:

... print(f)

提示 通过对可迭代对象调用内置函数iter,可获得一个迭代器。

>>> it = iter([1, 2, 3])

>>> next(it)

1

>>> next(it)

2

还可使用它从函数或其他可调用对象创建可迭代对象,详情请参阅库参考手册。

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20181218G06VPY00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 yunjia_community@tencent.com 删除。

扫码关注云+社区

领取腾讯云代金券