首页 > 代码库 > Python之路----------生成器

Python之路----------生成器

一、列表生成式

想想如何创建一个列表[0,1,2,3,4,5]

 1 l = [0,1,2,3,4,5] 

如果上面的列表元素足够多的话,是不是会写很多代码?看看列表生成式怎么写

1 #列表生成式
2 l = [x for x in range(6)]
3 
4 #上面的代码相当于
5 l = []
6 for x in range(6):
7     l.append(x)
8 
9 #用列表生成式可以节省代码,快速生成列表

二、生成器(generator)

什么是生成器?

通过列表生成式,我们可以直接创建一个列表。但是,受到内存限制,列表容量肯定是有限的。而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面几个元素,那后面绝大多数元素占用的空间都白白浪费了。

所以,如果列表元素可以按照某种算法推算出来,那我们是否可以在循环的过程中不断推算出后续的元素呢?这样就不必创建完整的list,从而节省大量的空间。在Python中,这种一边循环一边计算的机制,称为生成器(Generator)。

生成器只有在调用时才会生成相应的数据,生成器只记录当前位置并且生成器只有一个__next__()方法,但是一般不用next方法都用循环去调用生成器。

 1 import time
 2 a = time.time()
 3 l = [x for x in range(30000000)]
 4 b = time.time()
 5 print(b-a)
 6 
 7 a = time.time()
 8 g = (x for x in range(30000000))
 9 b = time.time()
10 print(b-a)
11 
12 
13 #l列表生成时间会很久,也很占内存,而g是用生成器没有耗时(原因是生成器调用才有数据)

斐波那契数列

斐波那契数列(Fibonacci sequence),又称黄金分割数列、因数学家列昂纳多·斐波那契(Leonardoda Fibonacci)以兔子繁殖为例子而引入,故又称为“兔子数列”,指的是这样一个数列:1、1、2、3、5、8、13、21、34、……在数学上,斐波纳契数列以如下被以递归的方法定义:F(1)=1,F(2)=1, F(n)=F(n-1)+F(n-2)(n>2,n∈N*)在现代物理、准晶体结构、化学等领域,斐波纳契数列都有直接的应用,为此,美国数学会从1963起出版了以《斐波纳契数列季刊》为名的一份数学杂志,用于专门刊载这方面的研究成果。

1 def fib(max):
2     n, a, b = 0, 0, 1
3     while n < max:
4         print(b)
5         a, b = b, a + b
6         n = n + 1

生成器函数版本:

1 def fib(max):
2     n, a, b = 0, 0, 1
3     while n < max:
4         yield b
5         a, b = b, a + b
6         n = n + 1

 

三、生成器牛逼的用法

生成器并行计算(简单的生产者消费者模型)异步IO模型雏形

 

 1 #coding=utf-8
 2 import time
 3 from random import choice
 4 
 5 def producer():
 6     mooncake = ["五仁馅", "咸蛋黄馅", "黑芝麻馅", "青红丝馅", "猪肉馅", "咸鱼馅"]
 7     c = consumer(Mr.A)
 8     c1 = consumer(Mis.B)
 9     c.__next__()
10     c1.__next__()
11     print("食品厂开始生产月饼了")
12     n = 0
13     while n < 3:
14         time.sleep(1)
15         mooncake1 = choice(mooncake)
16         print("食品厂生产了%s月饼" % mooncake1)
17         c.send(mooncake1)
18         mooncake2 = choice(mooncake)
19         print("食品厂生产了%s月饼" % mooncake2)
20         c1.send(mooncake2)
21         n += 1
22 
23 def consumer(name):
24     print("%s 准备开始吃月饼了" % name)
25     while True:
26         mooncake = yield
27         print("%s吃掉了%s月饼" % (name, mooncake))
28 
29 producer()

 

Python之路----------生成器