在Python中,这种一边循环一边计算的机制,称为生成器:
结论: 生成器本质是一个函数,不同于函数的是它生成的是一个对象,不执行函数内的代码
1.1. 列表生成器
列表生成器: 列表是直接生成数字在内存,可以随时调用
元组显示的类型是生成器,只存储在内存中,但是只有在调用的时候生成
b = [x for x in range(10)] c = (x for x in range(10)) print(b, c) print(type(b), type(c))
生成器的创建方法
1. c = (x for x in range(10)), 利用 ()来生成
2. 利用yield()方法
利用()生成
c = (x for x in range(10)) # print(c.next) 在Py2中的方法 print(c.__next__()) # 输出0,__next__()是一个私有方法,不建议用 print(next(c)) # 输出1, 利用next内置函数迭代输出,当输出到最有一个元素的时候,就不会输出数据 for i in c: # for调用C里面的next去迭代输出,节约内存空间 print(i, end=' ') # 2 3 4 5 6 7 8 9 ,因为前面输出了0,1,所以指针指向了下一位,所以从2开始
利用yield创建:如果一个函数定义中包含yield关键字,那么这个函数就不再是一个普通函数,而是一个generator
最难理解的就是generator和函数的执行流程不一样。函数是顺序执行,遇到return语句或者最后一行函数语句就返回。而变成generator的函数,在每次调用next()的时候执行,遇到yield语句返回,再次执行时从上次返回的yield语句处继续执行。
def fun(): print('ok') yield 1 # 有yield关键字,代表fun()非函数,是一个生成器 # 此时作为return 直接结束了函数 g = fun() # 此时的fun()是一个生成器对象,而非函数 print(g) # <generator object fun at 0x0000000000AFDEB8> a = next(g) print('a', a) # 接收了传递回来的值1 # next(g) # ok, 当遇到yield1的时候,可以认为是return 1,结束了函数的执行,g释放,所以后面的print在执行会报错 print(next(g)) # print()里面是一个可迭代对象,yield 1返回一个1被print捕捉到,所以 迭代输出 ok 和 1
生成器的send()方法:使用之前必须先进入到生成器里面,然后利用send()赋值给上次返回处
def fun(): print('ok1') count = yield 1 print(count) yield 2 b = fun() b.send(None) # 等价于 next(b),开始进入到函数, 直到遇到了yield 1后返回到此处,执行后面的b.send('hello world') tt = b.send('hello world') # 进入到退出的yield 1的位置,将'hello world'赋值给count进行打印,遇到yield 2后返回结果到此处 print(tt) # 将yield 2的结果赋给tt, 然后进行打印
生成器的应用
还可通过yield实现在单线程的情况下实现并发运算的效果
import time def consumer(name): print("%s 准备吃包子啦!" %name) while True: baozi = yield print("包子[%s]来了,被[%s]吃了!" %(baozi,name)) def producer(name): c = consumer('A') c2 = consumer('B') c.__next__() c2.__next__() print("老子开始准备做包子啦!") for i in range(10): time.sleep(1) print("做了2个包子!") c.send(i) c2.send(i) producer("ftl1012")
利用生成器实现斐波那契
def fib(max): n, b, a = 0, 0, 1 while n <= max: # print(b, end=' ') yield b # 等价于 print(b),将我们需要的结果先存放起来 b, a = a, b+a # 赋值是同时执行的 n += 1 gen = fib(6) print(next(gen)) print(next(gen)) print(next(gen)) print(next(gen))
【学习参考】http://www.cnblogs.com/alex3714/articles/5765046.html
【学习参考】http://www.cnblogs.com/yuanchenqi/articles/5830025.html