列表解析与生成器表达式
只要将列表解析式的[]改为()就是一个生成器,用next()或者for循环获得值
res=[x**2 for x in range(20) if x%2==0]
ret=(x**2 for x in range(20) if x%2==0)
print(res,ret)
#[0, 4, 16, 36, 64, 100, 144, 196, 256, 324]
#<generator object <genexpr> at 0x000001E29AD10DB0>
生成器函数
将函数中的return改为yield就是一个生成器函数
def generator(x):
yield x+1
g=generator(5)
print(g)
#<generator object generator at 0x0000015E8F3D8468>
一个生成器函数中可以有多个yield,在调用next()函数时碰到第一个yield停止,返回当前值.再次调用next()时从上次的yield位置继续往下运行,直到碰到下一个yield停止,返回当前值
import time
def test():
print('First number')
yield 1
time.sleep(3)
print('Second number')
yield 2
time.sleep(3)
print('Third number')
yield 3
time.sleep(3)
print('Forth number')
yield 4
for i in test():
print(i)
调用next()后不能再访问到之前的值,只能往下取得下一个yield的值
import time
def test():
print('First number')
yield 1
time.sleep(3)
print('Second number')
yield 2
time.sleep(3)
print('Third number')
yield 3
time.sleep(3)
print('Forth number')
yield 4
t=test()
next(t)
next(t)
for i in t:
print(i)
函数迭代器send()方法
send(value)可以把value的值赋给之前的yield然后继续运行上一个yield后的函数,可以认为给之前的yield赋值之后,再调用next()函数
import time
def test():
print('First number')
fir=yield 1
time.sleep(3)
print('Second number',fir)
yield 2
time.sleep(3)
print('Third number')
yield 3
time.sleep(3)
print('Forth number')
yield 4
t=test()
print(next(t))
print(t.send('is 1'))
通过生成器实现协程并行运算
import time
def consumer(name):
print('%s准备吃包子了'%name)
while True:
baozi=yield 'ヽ( ̄▽ ̄)ノ'
print('包子[%s]被%s吃了'%(baozi,name))
time.sleep(1)
def product():
c1=consumer('A')
c2=consumer('B')
print('开始做包子啦!')
print(next(c1))
print(next(c2))
for i in range(5):
print('做好了两个包子')
c1.send(i)
c2.send(i)
time.sleep(1)
product()