生成器(Generator)
生成器函数
# Python识别到这个函数中包含yield的关键字,因此该函数是一个生成器函数。
def simple_generator():
print("开始")
yield 1
print("继续")
yield 2
print("结束")
yield 3
g = simple_generator() # 生成器函数返回的是生成器,生成器是一个迭代器。
print(next(g)) # 开始
# 1
print(next(g)) # 继续
# 2
print(next(g)) # 结束
# 3
# print(next(g)) # StopIteration!
可以利用生成器这种简易写法,快速完成迭代器的编写。
def countdown(start):
"""生成器函数"""
while start >= 0:
yield start
start -= 1
# 调用生成器函数,返回生成器
cd = countdown(5)
print(type(cd)) # <class 'generator'>
for n in cd:
print(n, end=" ") # 5 4 3 2 1 0
生成器的特点:
- 惰性计算:只在需要时生成值,不占用大量内存
- 状态保存:每次
yield后暂停,下次从暂停处继续 - 一次性:和迭代器一样,只能遍历一次
链式调用
def sub_generator():
yield 1
yield 2
def main_generator():
yield "开始"
for value in sub_generator():
yield value
yield "结束"
for value in main_generator():
print(value)
# 开始
# 1
# 2
# 结束
可使用yield from 语法糖简化代码:
def main_generator():
yield "开始"
yield from sub_generator() # 委托给子生成器
yield "结束"
发送数据
当调用生成器的send函数的时候,可以向生成器发送数据,该数据会导致yield的表达式返回对应的值。
def calculator():
total = 0
while True:
x = yield total # yield 返回当前总数,并接收新值
if x is None:
break
total += x
calc = calculator()
print(next(calc)) # 输出: 0 (启动)
print(calc.send(10)) # 输出: 10 (发送10,累加后返回)
print(calc.send(20)) # 输出: 30
print(calc.send(5)) # 输出: 35
生成器表达式
类似列表推导式,但使用圆括号,返回生成器:
# 生成器表达式 —— 惰性计算,节省内存
squares_gen = (x**2 for x in range(1000000))
print(type(squares_gen)) # <class 'generator'>
# 按需获取值
print(next(squares_gen)) # 0
print(next(squares_gen)) # 1
print(next(squares_gen)) # 4




