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

时间:2021-09-29 12:43:44

一、列表生成式

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

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

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

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

二、生成器(generator)

什么是生成器?

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

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

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

 import time
a = time.time()
l = [x for x in range(30000000)]
b = time.time()
print(b-a) a = time.time()
g = (x for x in range(30000000))
b = time.time()
print(b-a) #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起出版了以《斐波纳契数列季刊》为名的一份数学杂志,用于专门刊载这方面的研究成果。

 def fib(max):
n, a, b = 0, 0, 1
while n < max:
print(b)
a, b = b, a + b
n = n + 1

生成器函数版本:

 def fib(max):
n, a, b = 0, 0, 1
while n < max:
yield b
a, b = b, a + b
n = n + 1

三、生成器牛逼的用法

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

 #coding=utf-8
import time
from random import choice def producer():
mooncake = ["五仁馅", "咸蛋黄馅", "黑芝麻馅", "青红丝馅", "猪肉馅", "咸鱼馅"]
c = consumer('Mr.A')
c1 = consumer('Mis.B')
c.__next__()
c1.__next__()
print("食品厂开始生产月饼了")
n = 0
while n < 3:
time.sleep(1)
mooncake1 = choice(mooncake)
print("食品厂生产了%s月饼" % mooncake1)
c.send(mooncake1)
mooncake2 = choice(mooncake)
print("食品厂生产了%s月饼" % mooncake2)
c1.send(mooncake2)
n += 1 def consumer(name):
print("%s 准备开始吃月饼了" % name)
while True:
mooncake = yield
print("%s吃掉了%s月饼" % (name, mooncake)) producer()