生成器:顾名思义是计算机自动生成的东西。我们采用列表来直观的了解一下生成器
首先定义一个列表,在不用生成器的情况下是这样子的:
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 就可以了,毕竟这是一个类似于中断的节点。