生成器和生成器表达式

一. 生成器
生成器的本质就是迭代器
生成器的特点和迭代器一样.取值方式和迭代器一样(__next__(), send(): 给上一个yield传值).
生成器一般由生成器函数或者生成器表达式来创建
其实就是手写的迭代器
def func():
    print("111")
    yield 222
gener = func() # 这个时候函数不会执行. 而是获取到⽣成器
ret = gener.__next__() # 这个时候函数才会执行. yield的作⽤和return一样. 也是返回数据
print(ret)

结果:
111
222
二. 生成器函数
和普通函数没有区别. 里面有yield的函数就是生成器函数.
生成器函数在执行的时候. 默认不会执行函数体. 返回生成器
通过生成器的__next__()分段执行这个函数.
send() 给上一个yield传值, 不能再开头(没有上一个yield), 最后一个yield也不可以用send()
def cloth():
    lst = []
    for i in range(0, 10000):
        lst.append("衣服"+str(i))
    return lst
cl = cloth()   
def cloth():
    for i in range(0, 10000):
        yield "衣服"+str(i)
cl = cloth()
print(cl.__next__())
print(cl.__next__())
print(cl.__next__())
print(cl.__next__())    

区别: 第一种是直接一次性全部拿出来. 会很占用内存. 第二种使用生成器. 一次就一个. 用多少生成多少. ⽣成器是一个一个的指向下一个. 不会回去, __next__()到哪, 指针就指到哪⼉.
下一次继续获取指针指向的值.

def eat():
    print("我吃什么啊")
    a = yield "馒头"
    print("a=",a)
    b = yield "⼤饼"
    print("b=",b)
    c = yield "⾲菜盒⼦"
    print("c=",c)
    yield "GAME OVER"

gen = eat() # 获取⽣成器
ret1 = gen.__next__()
print(ret1)
ret2 = gen.send("胡辣汤")
print(ret2)
ret3 = gen.send("狗粮")
print(ret3)
ret4 = gen.send("猫粮")
print(ret4)

send和__next__()区别:
1. send和next()都是让生成器向下走一次
2. send可以给上一个yield的位置传递值, 不能给最后一个yield发送值. 在第一次执成器代码的时候不能使⽤send()⾏⽣

三. 推导式
1. 列表推导式 [结果 for变量in可迭代对象 if条件筛选]
2. 字典推导式 {k:v for循环 条件筛选}
3. 集合推导式 {k for循环 条件}

四. 生成器表达式
(结果 for循环 条件)
特点:
1. 惰性机制
2. 只能向前
3. 节省内存(鸡蛋)

⽣成器表达式和列表推导式的区别:
1. 列表推导式比较耗内存. 一次性加载. 生成器表达式几乎不占用内存. 使用的时候才分
配和使用内存
2. 得到的值不一样. 列表推导式得到的是一个列表. 生成器表达式获取的是一个生成器.

原文地址:https://www.cnblogs.com/shanae/p/9469205.html