zoukankan      html  css  js  c++  java
  • 11-生成器

    一、如何得到自定义的迭代器(生成器)

    在函数内一旦存在yield关键字,调用函数并不会执行函数体代码

    会返回一个生成器对象,生成器即自定义的迭代器

    def func():
        print('第一次')
        yield 1
        print('第二次')
        yield 2
        print('第三次')
        yield 3
        print('第四次')
    
    
    g=func()              # 此时并不运行函数体代码
    print(g)              # <generator object func at 0x000001D009181740>
    # 生成器就是迭代器
    # g.__iter__()          均可调用
    # g.__next__()
    
    # next()或g.__next__ 会触发函数体代码的运行,然后遇到yield停下来,将yield后的值
    # 当做本次调用的结果返回
    res1=g.__next__()             # 打印第一次
    print(res1)                   # 1
    
    res2=g.__next__()             # 打印第二次
    print(res2)                   # 2
    
    res3=g.__next__()             # 打印第三次
    print(res3)                   # 3
    
    res4=g.__next__()             # 打印第四次,并抛出异常StopIteration

    二、应用案例

    def my_range(start,end=None,step=1):
    
        # 满足 range(5)---》0 1 2 3 4 的情况
        if end is None:
            output = 0
            while output < start:
                yield output
                output += step
        else:
    
        # 满足 range(0,5,2) 设定步长输出
            if step > 0:
                while start < end:
                    yield start
                    start += step
    
        # 满足range(5,0,-1) 步长为负时,逆走
            if step < 0:
                while start > end:
                    yield start
                    start += step

    测试:

    # 测试:
    for i in my_range(5,0,-2):
        print(i,end=" ")
    
    print("")
    
    for i in range(5,0,-2):
        print(i,end=" ")

    三、yield表达式 

    3.1 yield表达式介绍

    一般形式:x = yield 返回值

    使用 g.send(“xxx”)的方式给x传参,并且send在传参后自带next()功能

    但一个生成器开始时,需要进行初始化(g.send(None) 或 next(g))。若不初始化,将会有以下报错:

      

     3.2 yield表达式的使用案例

    def dog(name):
        food_list=[]
        print('道哥%s准备吃东西啦...' %name)
        while True:
            # x拿到的是yield接收到的值
            x = yield food_list # x = '肉包子'
            print('道哥%s吃了 %s' %(name,x))
            food_list.append(x) # ['一根骨头','肉包子']
    
    g=dog('alex')
    res=g.send(None)  # next(g)
    print(res)        # []
    
    res=g.send('一根骨头')
    print(res)        # ['一根骨头']
    
    res=g.send('肉包子')
    print(res)       # ['一根骨头', '肉包子']
    
    g.close()
    g.send('1111')  # 关闭之后无法传值 StopIteration

    四、总结yield

    有了yield关键字,我们就有了一种自定义迭代器的实现方式。yield可以用于返回值,但不同于return。
    函数一旦遇到return就结束了,而yield可以保存函数的运行状态挂起函数,用来返回多次值

    有了yield表达式,我们可以使函数的运行状态挂起,随时待命,等待我们再次传值给他。
  • 相关阅读:
    sphinx 源码阅读之分词,压缩索引,倒排——单词对应的文档ID列表本质和lucene无异 也是外部排序再压缩 解压的时候需要全部扫描doc_ids列表偏移量相加获得最终的文档ID
    详细说明XML分解(两)—DOM4J
    JSP简单的练习-用户登记表
    设计师给了px显着的单位,Android要设置多少开发商dip、dp、sp?
    左右xcode的重构选项的一些理解
    unicode下一个,读取数据库乱码问题
    java中间==、equals和hashCode差额
    MIPS台OpenWrt在系统内的路由器Rust应用程序开发
    Android采取async框架文件上传
    ios-上拉电阻负载许多其他接口
  • 原文地址:https://www.cnblogs.com/zhubincheng/p/12562447.html
Copyright © 2011-2022 走看看