2018-06-14 Python生成器
2018-06-14 本文已影响0人
Future石
生成器
创建生成器的方法
1.列表生成式将中括号改成小括号
#列表生成式
a = [x*2 for x in range(10)]
#生成器
b = (x*2 for x in range(10))
2.在def中使用yield关键字,不是创建方法,而是创建了一个生成器
斐波拉契数列
作为演示
除了第一个,第二个数字以外,任意一个数都由前面两个数相加得到:1,1,2,3,5,8,13,21,34......
创建一个生成斐波拉契数列的方法
def fib(times):
n = 0
a,b = 0,1
while n < times:
print b
a,b = b,a+b
n += 1
return 'Done'
fib(5)
创建一个生成斐波拉契数列的生成器
def fib(times):
n = 0
a,b = 0,1
while n < times:
yield b
a,b = b,a+b
n += 1
a = fib(6)
next(a)
next(a)
a.__next__()
yield的运行机制
next(a)
,a.__next__()
调用效果相同
def fib(times):
n = 0
a,b = 0,1
while n < times:
print ("----1----")
yield b
print ("----2----")
a,b = b,a+b
n += 1
a = test()
#for循环写起来更简洁
def fib(times):
a,b=0,1
for n in range(times):
yield b
a,b = b,a+b
#两种调用方式等效
next(a)
a.__next__()
运行至yield b 时停止,等到下一次调用,从a,b=b,a+b 处再次运行到下一次yield b时再次停止,循环♻️
send()方法和next()方法
temp = yield i
并不是把yield的值赋值给temp,而是在运行到yield i时接收send()传进的值,如果没传,等同传了None(send(None)
或者next()
)。
重点 传入的值需要变量来接收,每次传入的值到下一次yield
运行时需要重新传值,如果没传则又变成None
def test():
i = 0
while i < 5:
# 传值用变量temp接收
temp = yield I
print (temp)
i += 1
a = test()
send(None)
把None值给temp, next(a)
没有传值,相当于传了个None,效果一致
ps:负责生成数列的是yield ,next()和send()只是触发yield。
生成器第一次调用,不能使用send("haha")传值,需要先用next()
或者先传个Nonea.send(None)
先调用一次生成器才可以。
生成器的作用 - 完成多任务
任务切换的足够快,可以看成多个任务一起执行,这是一种多任务的实现方式-协程
多任务实现的三种方式:线程,进程,协程
def test1():
while True:
print ("--1--")
yield None
def test2():
while True:
print("--2--")
yield None
t1 = test1()
t2 = test2()
while True:
t1.__next__()
t2.__next__()