随堂笔记 19 day

简洁的列表解析形式 ----[ i for i in range(10) ]

生成器表达式           ----( i for i in range(10) )

自己的问题:

  return和yield可以连用吗? 不能,会报错。

def test():
    yield 1
    yield 2
    yield 3
res = test()
print(res)              #这样是打印生成器,不是yield返回值
print(res.__next__())   #这样才是打印yield返回值,调用next的方法

结果
<generator object test at 0x0000021CD6E99728>
1

 next----触发----yield

yield:

  1.返回值

  2.保留函数运行状态,基于从上次yield的结束末尾开始

消费者和生产者模型    

# 生产包子(100个)
第一种方法
def product_baozi1():
    ret = []
    for i in range(100):
        ret.append('包子%s'%i)
    return ret
baozi_list = product_baozi1()
print(baozi_list)


第二种方法
def product_baozi2():
    for i in range(100):
        print('正在生成包子')  #要一次用一次,有一个值就可以马上处理
        yield '一屉包子%s'%i
        print('开始买包子')
pro_g = product_baozi2()
baozi_1 = pro_g.__next__()
print(baozi_1)
baozi_2 = pro_g.__next__()
print(baozi_2)
baozi_3= pro_g.__next__()
print(baozi_3)

结果
['包子0', '包子1', '包子2', '包子3', '包子4', '包子5', '包子6', '包子7', '包子8', '包子9', '包子10', '包子11', '包子12', '包子13', '包子14', '包子15', '包子16', '包子17', '包子18', '包子19', '包子20', '包子21', '包子22', '包子23', '包子24', '包子25', '包子26', '包子27', '包子28', '包子29', '包子30', '包子31', '包子32', '包子33', '包子34', '包子35', '包子36', '包子37', '包子38', '包子39', '包子40', '包子41', '包子42', '包子43', '包子44', '包子45', '包子46', '包子47', '包子48', '包子49', '包子50', '包子51', '包子52', '包子53', '包子54', '包子55', '包子56', '包子57', '包子58', '包子59', '包子60', '包子61', '包子62', '包子63', '包子64', '包子65', '包子66', '包子67', '包子68', '包子69', '包子70', '包子71', '包子72', '包子73', '包子74', '包子75', '包子76', '包子77', '包子78', '包子79', '包子80', '包子81', '包子82', '包子83', '包子84', '包子85', '包子86', '包子87', '包子88', '包子89', '包子90', '包子91', '包子92', '包子93', '包子94', '包子95', '包子96', '包子97', '包子98', '包子99']


正在生成包子
一屉包子0
开始买包子
正在生成包子
一屉包子1
开始买包子
正在生成包子
一屉包子2

母鸡下蛋传说

#母鸡下蛋传说
第一种方法
def xiadan():
    ret = []
    for i in range(100):
        ret.append('鸡蛋%s'%i)
    return  ret
print(xiadan())
#缺点是占用空间大(内存)和效率低

第二种
def xiadan1():
    for i in range(100):
        yield '鸡蛋%s'%i
laomuji = xiadan1()
jidan = laomuji.__next__()
print('海绵宝宝取了',jidan)
jidan = laomuji.__next__()
print('海绵宝宝取了',jidan)
jidan = laomuji.__next__()
print('海绵宝宝取了',jidan)
结果
第一种 [
'鸡蛋0', '鸡蛋1', '鸡蛋2', '鸡蛋3', '鸡蛋4', '鸡蛋5', '鸡蛋6', '鸡蛋7', '鸡蛋8', '鸡蛋9', '鸡蛋10', '鸡蛋11', '鸡蛋12', '鸡蛋13', '鸡蛋14', '鸡蛋15', '鸡蛋16', '鸡蛋17', '鸡蛋18', '鸡蛋19', '鸡蛋20', '鸡蛋21', '鸡蛋22', '鸡蛋23', '鸡蛋24', '鸡蛋25', '鸡蛋26', '鸡蛋27', '鸡蛋28', '鸡蛋29', '鸡蛋30', '鸡蛋31', '鸡蛋32', '鸡蛋33', '鸡蛋34', '鸡蛋35', '鸡蛋36', '鸡蛋37', '鸡蛋38', '鸡蛋39', '鸡蛋40', '鸡蛋41', '鸡蛋42', '鸡蛋43', '鸡蛋44', '鸡蛋45', '鸡蛋46', '鸡蛋47', '鸡蛋48', '鸡蛋49', '鸡蛋50', '鸡蛋51', '鸡蛋52', '鸡蛋53', '鸡蛋54', '鸡蛋55', '鸡蛋56', '鸡蛋57', '鸡蛋58', '鸡蛋59', '鸡蛋60', '鸡蛋61', '鸡蛋62', '鸡蛋63', '鸡蛋64', '鸡蛋65', '鸡蛋66', '鸡蛋67', '鸡蛋68', '鸡蛋69', '鸡蛋70', '鸡蛋71', '鸡蛋72', '鸡蛋73', '鸡蛋74', '鸡蛋75', '鸡蛋76', '鸡蛋77', '鸡蛋78', '鸡蛋79', '鸡蛋80', '鸡蛋81', '鸡蛋82', '鸡蛋83', '鸡蛋84', '鸡蛋85', '鸡蛋86', '鸡蛋87', '鸡蛋88', '鸡蛋89', '鸡蛋90', '鸡蛋91', '鸡蛋92', '鸡蛋93', '鸡蛋94', '鸡蛋95', '鸡蛋96', '鸡蛋97', '鸡蛋98', '鸡蛋99'] 第二种 海绵宝宝取了 鸡蛋0 海绵宝宝取了 鸡蛋1 海绵宝宝取了 鸡蛋2

生成器总结:

  函数用return

  生成器用yield,可以保留状态

优点1.延迟计算,要的时候给你,也就是说,他不会一次性的生成所有的结果。这对于大数据处理,将会非常有用

  列表解析

    sum( [ i for i in range(10000000) ] )    内存占用大,机器容易卡死

  生成器表达式

    sum( i for i in range(10000000))  几乎不占内存

优点2.生成器有效提高代码可读性

人口普查

人口普查.txt
{'name':'北京','population':10100}
{'name':'南京','population':10200}
{'name':'东京','population':10300}

def get_population():
with open('人口普查.txt', 'r', encoding='utf-8') as f:
for i in f:
yield i
g1=get_population()
g=get_population() #将生成器赋值给g
# s1 = eval(g.__next__()) #用eval将字符结构提取出来进行运算,因为从文章截取为字符串类型
# print(s1['population']) #取人口数量
# print(g.__next__())

#总人口
# res = 0
# for p in g:
# p_dic = eval(p)
# print(p_dic['population'])
# res += p_dic['population']
# print(res)

#总人口(另一种)
for p in g:
all_popu = sum(eval(p)['population']for p in g)
print(int(all_popu))
for i in g1:
print(int(eval(i)['population'])/all_popu)

注意事项:将生成器赋值给g,如果前面迭代完了,后面g就不能再用,只能迭代一次

还有的是文件名称要写完全,和编码,什么编码写的就用什么编码解。

int和str不可以进行相除

生产者消费者模型

并发运行 就是同时运行——利用yield, 因为yield可以保留状态

python是顺序运行

补充

  1.yield相当于return控制的是函数的返回值

  2.x=yield 的另外一个特性,接收send传过来的值,赋值给x

def test():
    print('开始了')
    firt = yield 1     #默认firt=None
    print('第一次',firt)
    yield 2
    print('第二次')

t = test() #这样没有运行
res = t.__next__() #这样才算执行
print(res)

#生成器运行的方法有三种
1.t.__next__()
2.next(t)
3.t.send(None)   其中send有两个功能,一是可以触发生成器运行,接着运行。二是函数停留再firt那个位置,我就是给firt赋值的

单人的消费者模式

  单线程并发,来回的切换

def consumer(name):
    print('我是[%s],我准备开始吃包子了'%name)
    while True:
        baozi = yield
        print('%s很高兴把[%s]吃掉了'%(name,baozi))

def producer():
    c1 = consumer('wwe')
    c1.__next__()
    for i in range(10):
        c1.send('包子%s'%i)
producer()
原文地址:https://www.cnblogs.com/chrpy/p/8542454.html