生成器
創(chuàng)建生成器的方法
1.列表生成式將中括號(hào)改成小括號(hào)
#列表生成式
a = [x*2 for x in range(10)]
#生成器
b = (x*2 for x in range(10))
2.在def中使用yield關(guān)鍵字思喊,不是創(chuàng)建方法壁酬,而是創(chuàng)建了一個(gè)生成器
斐波拉契數(shù)列
作為演示
除了第一個(gè),第二個(gè)數(shù)字以外恨课,任意一個(gè)數(shù)都由前面兩個(gè)數(shù)相加得到:1舆乔,1,2剂公,3希俩,5,8诬留,13斜纪,21,34......
創(chuàng)建一個(gè)生成斐波拉契數(shù)列的方法
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)
創(chuàng)建一個(gè)生成斐波拉契數(shù)列的生成器
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的運(yùn)行機(jī)制
next(a)
,a.__next__()
調(diào)用效果相同
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循環(huán)寫起來更簡潔
def fib(times):
a,b=0,1
for n in range(times):
yield b
a,b = b,a+b
#兩種調(diào)用方式等效
next(a)
a.__next__()
運(yùn)行至yield b 時(shí)停止文兑,等到下一次調(diào)用盒刚,從a,b=b,a+b 處再次運(yùn)行到下一次yield b時(shí)再次停止,循環(huán)??
send()方法和next()方法
temp = yield i
并不是把yield的值賦值給temp绿贞,而是在運(yùn)行到y(tǒng)ield i時(shí)接收send()傳進(jìn)的值因块,如果沒傳,等同傳了None(send(None)
或者next()
)籍铁。
重點(diǎn) 傳入的值需要變量來接收涡上,每次傳入的值到下一次yield
運(yùn)行時(shí)需要重新傳值,如果沒傳則又變成None
def test():
i = 0
while i < 5:
# 傳值用變量temp接收
temp = yield I
print (temp)
i += 1
a = test()
send(None)
把None值給temp, next(a)
沒有傳值拒名,相當(dāng)于傳了個(gè)None吩愧,效果一致
ps:負(fù)責(zé)生成數(shù)列的是yield ,next()和send()只是觸發(fā)yield增显。
生成器第一次調(diào)用雁佳,不能使用send("haha")傳值,需要先用next()
或者先傳個(gè)Nonea.send(None)
先調(diào)用一次生成器才可以。
生成器的作用 - 完成多任務(wù)
任務(wù)切換的足夠快糖权,可以看成多個(gè)任務(wù)一起執(zhí)行堵腹,這是一種多任務(wù)的實(shí)現(xiàn)方式-協(xié)程
多任務(wù)實(shí)現(xiàn)的三種方式:線程,進(jìn)程星澳,協(xié)程
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__()