回顾
上节介绍了通过使用函数itertools.tee
复制生成器的方式来实现生成器多次遍历, 但这种方式为了复制出子生成器,仍需要花费额外的内存。
本节将介绍python生成器多次遍历的另一种方法------创建生成器类。
思路
通过重写接口函数__iter__
, 使类的对象可迭代;在迭代循环中使用关键词yield
,使iter函数变成生成器函数。每次实例化一个对象,遍历对象都会产生一个会生成可迭代内容的生成器。
举例
斐波那契数列生成器
class Fibonacci:
def __init__(self, num):
self.a = 0 # 第0个数是0
self.b = 1 # 第一个数是1
self.index = 1 # 从1开始
self.num = num # 共有num个数字
def __iter__(self):
while self.index <= self.num:
temp = self.a
self.a, self.b = self.b, self.b + temp
self.index += 1
yield self.a
print(iter(Fibonacci(5)))
# <generator object Fibonacci.__iter__ at 0x10dc12258>
print(list(Fibonacci(5)))
# [1, 1, 2, 3, 5]
print([i for i in Fibonacci(5)])
# [1, 1, 2, 3, 5]
等差数列生成器:
class ArithmeticProgression:
def __init__(self, begin, step, end=None):
self.begin = begin
self.step = step
self.end = end # 如果end为None,为无穷数列
def __iter__(self):
result = type(self.begin + self.step)(self.begin)
forever = self.end is None # forever为True, 数组为无穷数组
index = 0
while forever or result < self.end:
yield result
index += 1
result = self.begin + self.step * index
ap = ArithmeticProgression(0, 1, 3)
print(list(ap))
# [0, 1, 2]
优点
真正做到了轻松多次遍历生成器且不占用额外的内存资源
缺点
当生成器中的内容产生过程十分复杂时,遍历生成器时会相当耗时。
时间空间有时不可兼得。