# 生成器generator:一边循环一边计算的机制 # 相对于列表推导式来说,不必创建完整的列表,能够节省大量的空间
目录
1.创建生成器
方式1.使用列表推导式得到生成器:
方式2:next(生成器对象) ---系统内置的函数
方式3:通过‘函数+ yield’产生生成器
3.生成器方法send()
4.生成器应用--多任务
5.总结
1.创建生成器
方式1.使用列表推导式得到生成器:
# 方式1.使用列表推导式得到生成器:
# 只需要把列表推导式的[]换成(),就是生成器类型
# 例如:得到[0,10)中3的倍数的数值
res = (x*3 for x in range(10))
print(type(res))
# <class 'generator'>
print(res)
# <generator object <genexpr> at 0x000002B32733F620>
# 得到生成器里面的元素
print(res.__next__())
print(res.__next__()) # 每调用以此就生成一个元素
print(res.__next__())
方式2:next(生成器对象) ---系统内置的函数
# 方式2:next(生成器对象) ---系统内置的函数
# 每调用一次next(),就会产生一个元素
# PS:当让生成器产生元素过量的时候,会出现异常StopIteration
print(next(res)) # 9
print(next(res)) # 12
print(next(res)) # 15
print(next(res)) # 18
# 处理这种异常StopIteration
while True:
try:
e = next(res)
print(e)
except:
print('没有更多元素了!')
break
# 21
# 24
# 27
# 没有更多元素了!
方式3:通过‘函数+ yield’产生生成器
'''
通过函数产生生成器
步骤:
1.定义一个函数,函数中使用yield关键字
2.调用函数,接收调用的结果
3.得到的结果就是生成器
4.借助于next(),__next__()得到元素
'''
# yield
# 只要函数中出现了yield关键字,函数就不是函数了,而是变成了生成器
def func():
n = 0
while True:
n += 1
yield n # yield n 的作用相当于:return n + 暂停【暂停在该位置,下次再调用的时候从此位置开始】
g = func()
print(g) # <generator object func at 0x00000189D61AF620>
print(next(g)) # 1
应用:斐波那契数列
# 斐波那契数列
def fib(length):
a, b = 0, 1
n = 0
while n < length:
yield b
a, b = b, a+b
n += 1
return '没有更多元素了!!!' # 返回错误信息
g = fib(6)
print(next(g))
print(next(g))
print(next(g))
# 1
# 1
# 2
3.生成器方法send()
# 生成器之方法send()
# 向每次调用生成器的时候传值,第一次调用需要传入None
def gen():
i=0
while i<5:
temp = yield i
print('temp:',temp)
i+=1
return '没有元素了'
g = gen()
# print(next(g))
# print(next(g))
# print(next(g))
# # 0
# # temp: None
# # 1
# # temp: None
# # 2
# g.send(None)
print(g.send(None)) # 第一次要用g.send(None)
n1 = g.send('mico')
print('n1:',n1)
n2 = g.send('xiaoha')
print('n2:',n2)
# 0
# temp: mico
# n1: 1
# temp: xiaoha
# n2: 2
4.生成器应用--多任务
# 进程>线程>协成
# 进程
# 线程
# 协程:线程的小分支
# 1.不加协程的时候-----------【全部做完菜,再做汤】----------------------
def task1(n):
for i in range(n):
print('正在做第{}个菜*****'.format(i))
i += 1
def task2(n):
for i in range(n):
print('正在做第{}个汤-----'.format(i))
i += 1
task1(3)
task2(3)
# 这样执行的结果为:【全部做完菜,再做汤】
# 正在做第0个菜*****
# 正在做第1个菜*****
# 正在做第2个菜*****
# 正在做第0个汤-----
# 正在做第1个汤-----
# 正在做第2个汤-----
# 2.加协程的时候----------【一边做菜,一边做汤】-----------------------
def task1(n):
for i in range(n):
print('正在做第{}个菜*****'.format(i))
i += 1
yield # yield不加n的时候,只是用了其暂停功能,不抛出值
def task2(n):
for i in range(n):
print('正在做第{}个汤-----'.format(i))
i += 1
yield
g1 = task1(3)
g2 = task2(3)
while True:
try:
g1.__next__()
g2.__next__()
except:
pass
# 运行结果为:【一边做菜,一边做汤】
# 正在做第0个菜*****
# 正在做第0个汤-----
# 正在做第1个菜*****
# 正在做第1个汤-----
# 正在做第2个菜*****
# 正在做第2个汤-----
5.总结
--创建生成器:
1.列表推导式
2.函数+yield
--产生元素:
1.next(generator)
2.生成器自己的方法:
g.__next__()
g.send(value)
--应用:协成
PS:部分内容参考千锋教育,如有侵权,请联系删除!谢谢!