,

python 生成器

生成器(Generator) 生成器函数 可以利用生成器这种简易写法,快速完成迭代器的编写。 生成器的特点: …

生成器(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

生成器的特点:

  1. 惰性计算:只在需要时生成值,不占用大量内存
  2. 状态保存:每次 yield 后暂停,下次从暂停处继续
  3. 一次性:和迭代器一样,只能遍历一次

链式调用

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

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

About the Author

每个人都有自己得时区,在自己得时区里,一切都是准时的。

BlockSpare — News, Magazine and Blog Addons for (Gutenberg) Block Editor