# 今日主要内容(重要)
# 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
# 只能向前. 不能反复.