day12 生成器(重要)

# 今日主要内容(重要)
# 1. 迭代器
# __iter__() 获取迭代器
# __next__() 下一个
#
# 2. 生成器
# 本质就是迭代器
# 两种方式获取生成器
# 1. 通过生成器函数
# 2. 通过生成器表达式
#
# 3. 生成器函数
# 函数内部有yield. yield返回 -> return(生成器函数不要用)
# yield可以把函数分段执行 这里区别于return(直接停止函数的执行)
# 生成器函数被调用的时候. 返回生成器
# def func():
# yield
# g = func() - 得到生成器 不是执行
# 生成器函数. 就是把return换成yield
def gen():
    print("爽歪歪")
    yield "娃哈哈" # 可以让我们的函数分段运行
    print("酸酸乳")
    yield "AD钙奶"
    print("黄焖鸡米饭")
ret = gen() # 不会执行你的函数, 获取到生成器对象
# # 迭代器不能等价代换
print(ret) # <generator object gen at 0x00000195518CFE60> generator 生成器
print(ret.__next__()) # 必须执行__next__()才可以触发生成器的运行 娃哈哈
print(ret.__next__()) # 必须执行__next__()才可以触发生成器的运行 AD钙奶
print(ret.__next__()) # StopIteration 迭代器, 就找yield, 执行不到才会报错
View Code
# 
# 生成器的用法和迭代器基本一致
# __next__() 开始执行生成器 . 执行到yield. 直到没有yield. 抛出StopIteration
#
# send() 可以给上一个yield传值
# 生成器还可以使用__next__(), send()来访问生成器
# send()可以给上一个yield位置传值

def func():
    print("水饺")
    a = yield "大馅水饺"
    print("a=", a)
    print("烧饼")
    b = yield "武大郎烧饼"
    print("b=",b)
    print("老婆饼")
    c = yield "只要老婆不要饼"
    print("c=", c)
#
#
gen = func() # 生成器
print("返回值是:", gen.__next__())
print("返回值是:",gen.send("混沌面")) #  和__next__()一样也是向下找yield. 给上一个yield传值
print("返回值是:",gen.send("胡辣汤")) #  和__next__()一样也是向下找yield. 给上一个yield传值
print("返回值是:",gen.send("马拉")) #  和__next__()一样也是向下找yield. 给上一个yield传值

#  send()不可以在第一个位置和最后一个位置出现
#  最后的yield后的代码是可以执行的但是会报错. StopIteration
View Code
      迭代器特点:
# 1. 省内存
# 2. 惰性机制, 不访问__next__() 就没有值.
# 3. 只能向前. 不能反复.
#     补充: yield from
def gen():
    lst = ["⿇花藤", "胡辣汤", "微星牌饼铛", "Mac牌锅铲"]
    lst2 = ["饼铛还是微星的好", "联想不能煮鸡蛋", "微星就可以", "还可以烙饼"]
    yield from lst
    yield from lst2
g = gen()
for el in g:
    print(el)
# 效果:
# 麻花藤
# 胡辣汤
# 微星牌饼铛
# Mac牌锅铲
# 饼铛还是微星的好
# 联想不能煮鸡蛋
# 微星就可以
# 还可以烙饼
View Code
# 
# 4. 各种推导式(简单)
# 列表推导式 [结果 for循环 if判断]
# 字典推导式 {key: value for循环 if判断}
# 集合推导式 {key for循环 if判断}
#
# 5 .生成器表达式(最难)
# (结果 for循环 if判断)
# 惰性机制, 不访问__next__() 就没有值.
def func():     # 生成器函数
    print(111)
    yield 222
#
g = func()      #  生成器 -> 没有执行过__next__()
g1 = (i for i in g)     # 生成器表达式. 也没有__Next__()
g2 = (i for i in g1)    # 生成器表达式. 也没有__Next__()
# # 到此为止, 没有人拿过值
#
print(list(g2))     # 111 [222]
print(list(g))      # []
print(list(g1))     # []
# list() 含有__next__()  
View Code
#          只能向前. 不能反复.

猜你喜欢

转载自www.cnblogs.com/Knight-huang/p/9892580.html