生成器和推倒式

    1.生成器的本质就是迭代器
    首先,我们先看一个函数:
    def func():
        print("111")
        return 222
    ret = func()
    print(ret)
    结果:
    111
    22
    将函数的return替换成yield就是生成器:
    def func():
        print('111')
        yield 222
    ret = func()
    print(ret)
    结果:
    <generator object func at 0x10567ff68>
    运行的结果和上面的不一样,就是因为函数中存在了一个yield,那么这个函数就i是一个生成器函数
    这个时候我们再执行这个函数的时候,就不再是函数的执行了,而是获取这个生成器
    接下来如何使用呢?
    想想迭代器,生成器的本质就是迭代器,所以,我们可以直接执行__next__()来执行以下的生成器:
    def func():
        print("111")
        yield 222
    gener = func()  # 这个时候函数不会执行. 而是获取到生成器
    ret = gener.__next__()  # 这个时候函数才会执行. yield的作用和return一样. 也是返回数据
    print(ret)
    结果:
    111
    222
    那么我们就可以看到,yield和return的效果是一样的.都可以返回值.
    有什么区别呢?yield是分段来执行一个函数.return呢?直接停止执行函数

    那么生成器有什么作用呢?
    最简单的说就是节省内存

    注意:生成器函数被执行. 获取到的是生成器. 而不是函数的执行

    2.生成器的三种创建办法:
        1.通过生成器函数
        2.通过生成器表达式创建生成器
        3.通过数据转换

    3.send(值)和__next__()的区别:
    send和next都是让生成器向下走一次
    send可以给是上一个yield的位置传递值,不能给最后一个yield发送值,在第一次执行生成器代码的时候不能使用send
    生成器可以使用for循环来循环获取内部的元素

    取值:
    1.
    __next__()
    2.
    send(值)
    给上一个yield位置传一个值, 第一个和最后一个yield不用传值
    3.
    可以for循环
    4.
    list(g)

    4.生成器表达式:

        (结果 for 变量 in 可迭代对象 if 筛选)
        例如:
        简单的来一个:给出一个列表,通过循环,向列表中添加1-15:
        lst = []
        for i in range(1-16):
            lst.append(i)
        print(lst)
        按照之前的推倒式格式转换成下面代码:
        lst = [i for i in range(1-16)]
        print(lst)
        列表推倒式是通过一行来构建你要的列表,列表推倒式看起来代码简单,但是出现错误后很难排查
        筛选模式
        [结果 for 变量 in 可迭代对象 if 条件]
        lst = [i for i in range(1, 100) if i % 2 == 0]  # 获取100以内的所有偶数

        生成器的表达式和列表的推倒式语法上基本上是一样的,就是把[]换成()
        gen = (i for i in range(1, 100) if i % 2 == 0)
        print(gen)
        这时候我们的到的结果是:
        <generator object <genexpr> at 0x106768f10>
        打印的结果就是一个生成器,由此也可以看出生成器表达式可以进行筛选.
       
        生成器表达式和列表推倒式的区别:
        1.列表推倒式比较耗内存,一次性加载,生成器表达式几乎不占内存,使用的时候才分配和使用内存
        2.得到是值不一样,列表推倒式得到是一个列表,生成器表达式获取的是一个生成器
       
        生成器的惰性机制:
        生成器之后再访问的时候才取值,说白了就是不找他要他才会给你值,不找他要,他是不会执行的
   

        字典推倒式 {结果 for 变量 in 可迭代对象 if 筛选} 结果=>key:value
        根据名字也不难看看出,就是推导出来的是字典
       
        集合推倒式 {结果 for 变量 in 可迭代对象 if 筛选} 结果=>key
        推导出来是集合,自带去重功能

        总结:推倒式有,列表推倒式,字典推倒式,集合推倒式
        元组是没有推倒式的.切记

 

原文地址:https://www.cnblogs.com/kongjubeihou/p/9330056.html