python生成器(generator):是一种特殊的迭代器,优势是可以在运行中途改变函数里的参数。
如何判断一个对象是否是一个生成器:
from _collections_abc import generator
list_num = (x for x in range(10))
print(isinstance(list_num, generator)) # True
print(type(list_num)) # <class 'generator'>
生成器创建一(类似列表推导式):
列表推导式是 [ ],生成器是 ( )
list_num = (x for x in range(10))
生成器创建二:
函数内部使用了 yield ,那么执行函数就会得到一个生成器。
from _collections_abc import generator
def a():
for i in range(10):
yield i
a = a()
print(isinstance(a, generator)) # True
print(next(a)) # 0
print(next(a)) # 1
print(next(a)) # 2
print(next(a)) # 3
生成器的执行顺序:
def gen():
i = 0
while i < 5:
# 8(程序再次运行到yield,获取了返回值后,会执行第二次next后的代码)
yield i # 3(当程序运行到yield时,返回 值,下面的next拿到返回值后,会紧接着执行next后面的程序)
print('i = ', i) # 6(当第二次next执行后,会从上一次跳出的地方继续执行,也就是yield返回后紧接着的代码)
i += 1 # 7(当执行完了函数时,会重写执行这个函数,知道下一次yield跳出,)
# 函数内部使用了yield 那么执行就会得到一个生成器的对象
g = gen()
print(111111111111) # 1
print(next(g)) # 2(当用next获取yield返回值时程序跳到函数内部)
print(22222222222222) # 4
print(next(g)) # 5
print(3333333333333) # 9(然后循环这个执行顺序)
print(next(g))
print(444444444444444444)
print(next(g))
生成器的 send 方法:
作用:在程序运行时,可以修改其中的属性值。send可以像next一样,唤醒函数,从yield后一行执行。
def a():
i = 0
while i < 10:
# 这个temp值是来接收send传入的参数的
temp = yield i
print('temp:', temp)
i += 1
g = a()
# TypeError: can't send non-None value to a just-started generator
# 生成器执行一开始不能发送一个非空上的值
# g.send('www')
print(next(g))
print(next(g))
print(next(g))
"""
用send能唤醒yield,让程序继续往下走,
‘www’是发送给了temp,temp可以把接收到
的值赋值给任何一个变量,达到一个函数前段
时间执行一个程序,后半段时间,执行修改后的程序
这也是生成器的一个特点
"""
print(g.send('www'))
print(next(g))
print(next(g))
# 结果
# 111111111111
# 0
# 22222222222222
# i = 0
# 1
# 3333333333333
# i = 1
# 2
# 444444444444444444
# i = 2
# 3
小例:用生成器写一个斐波拉契数列。
def fbl(num):
a, b = 0, 1
for i in range(num):
a, b = b, a+b
yield a
i = fbl(10)
print(type(fbl))
# <class 'generator'>
print(type(i))
for c in i:
print(c)
如有错误,欢迎评论或私信指正。