Lucas

导航

生成器(generator)以及利用生成器(generator)产生并行效果

生成器:顾名思义是计算机自动生成的东西。我们采用列表来直观的了解一下生成器

首先定义一个列表,在不用生成器的情况下是这样子的:

a = [0,1,2,3,4,5,6,7,8,9]
print(a)

运行结果:

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

Process finished with exit code 0

可以看到,这样定义列表,系统默认在内存在开辟出一块地址用来存储列表a,但是当这个列表足够大,就会导致程序短暂的卡死。接下来我们来看列表生成器:

#列表生成器格式(  )
a = (i for i in range(10))
print(a)

运行结果:

<generator object <genexpr> at 0x00000000006E0480>

Process finished with exit code 0

可以看到,这是在内存中开辟了一块地址,并没有将数据存入进去,这样程序运行速度就很加快。

当我们需要取出列表生成器产生的数据时有两种方法:第一种是迭代,通俗的讲也就是for循环,如下:

a = (i for i in range(10))
for number in a :
    print(number)

结果:

0
1
2
3
4
5
6
7
8
9

Process finished with exit code 0

另一种方法是:__next__(注意是两个_)方法,取下一个:

a = (i for i in range(10))
print(a.__next__())
print(a.__next__())
print(a.__next__())
print(a.__next__())
print(a.__next__())

运行结果:

0
1
2
3
4

Process finished with exit code 0

了解了生成器之后,我们采用生成器实现程序的并行效果:

要点:当定义函数时,函数体中包含关键字 yield 时,那么这个函数就会变成一个生成器。每当调用一次__next__(),程序会运行到 yield 退出,再次调用__next__()时,生成器从yield开始执行,到下一次碰到 yield 为止。下面是一个采用生成器实现简单的供需关系:

#简单供需关系

def consumer(name):  #定义一个生成器
    print("[%s]准备吃包子了!"%(name))
    while True:
        baozi = yield
        print("[%s]包子来了,[%s]吃掉了它!"%(baozi,name))

def deal():
    one = consumer("lucas") #格式化生成器
    one.__next__()  #进入生成器开始执行,执行到yield 退出生成器,此时生成器定位在yield
    print("厨师开始做包子了!")
    one.send("韭菜陷") #进入生成器,将send的内容赋给yield,并从yield开始执行,执行到下一次yield终止(有循环)或者执行完生成器(无循环)

deal()

运行结果:

[lucas]准备吃包子了!
厨师开始做包子了!
[韭菜陷]包子来了,[lucas]吃掉了它!

Process finished with exit code 0

对于生成器,牢记 yield 就可以了,毕竟这是一个类似于中断的节点。

 

posted on 2017-10-12 16:23  莲蓉馅的和氏璧  阅读(505)  评论(0编辑  收藏  举报