在编程中我们经常会用到列表, 以前使用列表时需要声明和初始化, 在数据量比较大的时候也需要把列表完整生产出来, 例如要存放 1000 给数据, 需要准备长度 1000 的列表, 这样计算机就需要准备内存放置这个列表, 在 Python 中, 这种一边循环一边计算的机制, 称为生成器: generator, 这个功能在列表使用时比较节省空间, 使用方法:
- g=(i*2 for i in range(10))
- data=g.__next__()
- print(d)
取列表时 data=g.__next__(), 此时才去生成.
应用: 生成斐波拉契数列
- def fig(num):
- n,a,b=0,0,1
- while n<num:
- yield b
- a,b=b,a+b
- n+=1
- return 'done'
fig(10) 定义长度为 10 的数列
- fig(10)
- for i in range(10):
- try:
- x=next(g)
- print(x)
- except StopIteration as e:
- print('error %s' % e.value)
- break
运行结果:
- 1
- 1
- 2
- 3
- 5
- 8
- 13
- 21
- 34
- 55
这里, 最难理解的就是 generator 和函数的执行流程不一样. 函数是顺序执行, 遇到 return 语句或者最后一行函数语句就返回. 而变成 generator 的函数, 在每次调用 next() 的时候执行, 遇到 yield 语句返回, 再次执行时从上次返回的 yield 语句处继续执行.
还可通过 yield 实现在单线程的情况下实现并发运算的效果
- import time
- def customer(name):
- print('%s 要吃包子' %name)
- while True:
- baozi=yield
- print('%s 包子来了, 很快就被 %s 吃了' %(baozi,name) )
- return '出错了' #抛出异常
- def producter(name,student,num):
- g=customer(student) #** 要吃包子
- g.__next__()
- print('%s 厨师了解到 %s 要吃包子, 开始做包子' %(name,student))
- for i in range(num):
- time.sleep(1) #用时 1 秒
- g.send('韭菜馅') #包子做好, 送给学生
- print('包子卖完了')
- # 张厨师, 学生今天中午吃包子, 用 10 斤面做 20 个包子
- producter('张厨师','学生',10)
运行结果:
学生要吃包子
张厨师厨师了解到学生要吃包子, 开始做包子
韭菜馅包子来了, 很快就被学生吃了
韭菜馅包子来了, 很快就被学生吃了
韭菜馅包子来了, 很快就被学生吃了
韭菜馅包子来了, 很快就被学生吃了
韭菜馅包子来了, 很快就被学生吃了
韭菜馅包子来了, 很快就被学生吃了
韭菜馅包子来了, 很快就被学生吃了
韭菜馅包子来了, 很快就被学生吃了
韭菜馅包子来了, 很快就被学生吃了
韭菜馅包子来了, 很快就被学生吃了
包子卖完了
来源: http://www.bubuko.com/infodetail-3169742.html