• 10 迭代器与生成器


    迭代与递归
    迭代器协议:对象必须提供一个next方法 执行该方法要么返回迭代中下一项
    要么引起一个stoplteration异常 以终止迭代
    可迭代对象: 实现了迭代器协议的对象
    协议是一种约定:可迭代对象实现了迭代器协议 Python的内部工具
    (如for循环 sum max min函数等等)使用迭代器协议访问对象

    for循环式中 调用了不可迭代对象内部的_iter_方法,把它们变成了可迭代

    考虑序列型和非序列型 不可用列表下标 只可迭代器协议

    啥是生成器:可以理解为一种数据类型 它自动实现了迭代器协议
    故生成器就是可迭代对象
    生成器在Python中表现:
    1.生成器函数 常规函数定义 但是 使用yield语句而不是return返回结果
    yield语句一次返回一个结果

    def test():
        yield 1
        yield 2
        yield 3
    g=test()
    print(g)
    print(g._nest_)
    print(g._nest_)


    2.生成器表达式 类似于列表推导 但是生成器返回按需产生结果的一个对象
    而不是构建一个结果列表
    生成器的优点:
    对延迟操作提供了支持 不是立即产生结果 可在需要时产生

    小结:
    1,是可迭代对象
    2、实现了延迟计算节省内存!

    三元表达式

    name='alex'
    res='SB' if name=='alex' else ' 帅 哥'    
    print(res)


    列表解析

    egg_list=[]
        for i in range(10)
        egg_list.append('鸡蛋%s' %i)
    print(egg_list)
    #or
    [鸡蛋%s '%i for i in range(10)'] #二元
    #or
    [鸡蛋%s '%i for i in range(10)' if i >5]    #三元,没有四元



    1.把列表解析的【】换成()得到的就是生成器表达式
    2、列表解析与生成器都是一直能够便利的编程方式,只不过生成器
    表达式更省内存
    3、Python不但使用迭代器协议 让for循环更加通用,大部分函数
    也是使用迭代器协议访问对象的

    sum([i for i in range (10)])    #列表解析
    
    sum=(i for i in range (10))    #生成器表达式 几乎不占用内存
    
    def test():    #生成器函数
        yield 1
        yield 2
        yield 3
        yield 4
    res=test()
    print(res)
    print(res._next_())
    print(res._next_())
    print(res._next_())
    
    生成器的好处:
    吃包子例子:
    def product_baozi():
        ret[]
        for i in range(100)
            ret.append('包子%s'%i)
        return ret
    boazi_list=product_baozi()
    print(product)
    
    #or
    def product_baozi():
        for i in range(100)
            yield 'baozi%s'%i
    pro_g=produce_baozi()
    
    baozi1=pro_g._next_()
    print('来一个人吃包子',baozi1)
    baozi2=pro_g._next_()
    print('来一个人吃包子',baozi2)
    baozi3=pro_g._next_()
    print('来一个人吃包子',baozi3)
    
    #做一个返回值就输出 执行效率更好
    
    def product_egg():
        ret[]
        for i in range(100)
            ret.append('鸡蛋%s'%i)
        return ret


    #缺点1.占空间大 2.效率低

    def product_egg():
        for i in range(100)
            yield '鸡蛋%s'%i
    a=xiadan()
    jidan=a._next_
    print('XXX取鸡蛋',jidan)



    生成器特性:
    语法上类似函数:不同于 一次返回一个值
    自动实现迭代器协议:
    状态挂起:使用yield返回一个值 然后挂起函数状态 下次从离开的地方重新开始

    优点:延迟计算 一次返回一个结果
    提高代码可读性
    注意事项:生成器只能遍历一次

    生产者消费者模型:

    #反例:
    import time
    def producer():
        ret=[]
        for i in range(100):
            time.sleep(0.1)
        ret.append('包子%s'%i)
        return ret
    
    def consumer(res):
        for index,baozi in enumerate(res):
            time.sleep(0.1print('第%s个人,吃了%s'%(index,baozi))
    
    res=producer()
    consumer(res)
    
    #yield相当于return控制函数返回值
    #x=yield 另一个特性 接受send传过来的值 赋值给x
    
    def test():
        print('开始啦')
        first=yield 
        print('第一次',first)
        yield 2
        print('第二次')
    t=test()
    res=t._next_()
    print(res)
    t._next_()
    res=t.send('函数停留在first位置 我是给first赋值的')
    print(res)
    
    
    #正例;
    def consumer(name):
        print('我是[%s],我准备开始吃包子了'%name)
        while True:
            baozi=yield
        print('%s 开心的吃掉了%s'%[name,baozi])
    def producer():
        c1=consumer('aaa')
        c2=consumer('bbb_sb')
        c1.__next__()
        c2.__next__()
        for i in range(10):
            time.sleep(1)
            c1.send('韭菜馅包子%s',%i)
            c2.send('韭菜馅包子%s',%i)
    producer()
  • 相关阅读:
    HTML5基础知识(1)--上标和下标文本
    jQuery基础--样式篇(5)
    jQuery基础--样式篇(4)
    jQuery基础--样式篇(3)
    jQuery基础--样式篇(2)
    jQuery基础--样式篇(1)
    使用D3绘制图表(7)--饼状图
    使用D3绘制图表(6)--竖直柱状图表
    安装Centos 7 错误解决
    linux下搭建LAMP
  • 原文地址:https://www.cnblogs.com/louzhiyuan/p/10415732.html
Copyright © 2020-2023  润新知