回顧
上節(jié)介紹了通過使用函數(shù)itertools.tee
復(fù)制生成器的方式來實(shí)現(xiàn)生成器多次遍歷, 但這種方式為了復(fù)制出子生成器芜茵,仍需要花費(fèi)額外的內(nèi)存猬腰。
本節(jié)將介紹python生成器多次遍歷的另一種方法------創(chuàng)建生成器類削祈。
思路
通過重寫接口函數(shù)__iter__
, 使類的對象可迭代擎淤;在迭代循環(huán)中使用關(guān)鍵詞yield
岳链,使iter函數(shù)變成生成器函數(shù)花竞。每次實(shí)例化一個對象,遍歷對象都會產(chǎn)生一個會生成可迭代內(nèi)容的生成器掸哑。
舉例
斐波那契數(shù)列生成器
class Fibonacci:
def __init__(self, num):
self.a = 0 # 第0個數(shù)是0
self.b = 1 # 第一個數(shù)是1
self.index = 1 # 從1開始
self.num = num # 共有num個數(shù)字
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]
等差數(shù)列生成器:
class ArithmeticProgression:
def __init__(self, begin, step, end=None):
self.begin = begin
self.step = step
self.end = end # 如果end為None约急,為無窮數(shù)列
def __iter__(self):
result = type(self.begin + self.step)(self.begin)
forever = self.end is None # forever為True, 數(shù)組為無窮數(shù)組
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]
優(yōu)點(diǎn)
真正做到了輕松多次遍歷生成器且不占用額外的內(nèi)存資源
缺點(diǎn)
當(dāng)生成器中的內(nèi)容產(chǎn)生過程十分復(fù)雜時,遍歷生成器時會相當(dāng)耗時苗分。
時間空間有時不可兼得厌蔽。