python 生成器
前言:
列表生成式
a1=[0, 2, 4, 6, 8, 10, 12, 14, 16, 18] a2=[i*2 for i in range(10)] print(a2) >>>>>>>>> [0, 2, 4, 6, 8, 10, 12, 14, 16, 18] [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
a3=[] for i in range(10): i=i*2 a3.append(i) print(a3)
问题描述:循环的功能时,后面没用到的数就浪费内存空间
解决思路:循环到哪,才调用该列表元素,此时再生成该元素,就可以节省内存空间
问题点:
有规律的数据,知道怎么生成;
没规律的数据,怎么生成呢?
有规律的数据:
a4=(i*2 for i in range(10)) print(type(a4)) print(a4)
>>>>>
<class 'generator'>
<generator object <genexpr> at 0x0133AEA0>
生成器和列表的区别:只有循环到了,才会生成该元素。所以不能用切片的方式取值,只能用循环一个一个取值
总结:
1、只有在调用时,才会生成相应的数据。
2、只记住当前生成的数据,前面生成的数据都记不得了,只能往后生成数据
3、只有一个--next--()方法
生成器的方法:
1、next()调用yield,但不会给yield的传值
2、send()调用yield,给yield传值
使用send()函数之前必须使用__next__(),因为先要中断,当第二次调用时,才可传值,如下:
- 直接调用send(),不使用next()
def customer(name): print("%s准备吃包子了" % name) while True: baozi = yield print("包子【%s】来了,被【%s】吃了" % (baozi, name)) a=customer("jack") c=a.send("韭菜馅")
>>>>>>>>>>>>>>>>>>
Traceback (most recent call last):
File "E:/2.py", line 9, in <module>
c=a.send("韭菜馅")
TypeError: can't send non-None value to a just-started generator
- 2、使用send()前,先使用__next()__
def customer(name): print("%s准备吃包子了" % name) while True: baozi = yield print("包子【%s】来了,被【%s】吃了" % (baozi, name)) a=customer("jack") a.__next__() c=a.send("韭菜馅")
>>>>>>>>>>>>>>>>>
jack准备吃包子了
包子【韭菜馅】来了,被【jack】吃了
案例:
单线程的并行效果(实际还是串行)
#消费者 def customer(name): print("%s准备吃包子了"%name) while True: baozi=yield print("包子【%s】来了,被【%s】吃了"%(baozi,name)) #生产者 def producter(name): c1=customer("顾客1") c2 = customer("顾客2") c1.__next__() c2.__next__() print("%s准备做包子了"%name) for i in range(2): print("---做了1个包子,分2半----") c1.send("包子1") c2.send("包子2") producter('jack')
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
顾客1准备吃包子了
顾客2准备吃包子了
jack准备做包子了
---做了1个包子,分2半----
包子【包子1】来了,被【顾客1】吃了
包子【包子2】来了,被【顾客2】吃了
---做了1个包子,分2半----
包子【包子1】来了,被【顾客1】吃了
包子【包子2】来了,被【顾客2】吃了