第十三天-生成器

# 生成器:
# 生成器实质就是迭代器(省内存 惰性机制 只往前)
# 1. 通过生成器函数
# 2. 通过各种推导式来实现生成器

# def func():
# yield
#
# g = func() - 得到生成
 1 # 生成器函数  就是把return 换成yield
 2 # return  换成 yield 理解成一次性执行 只往前
 3 def fu():
 4     print("娃哈哈")
 5     yield "哈哈娃"  # yield可以把函数分段执行
 6     print("AD钙")
 7     yield "美滋滋"
 8     print("爽歪歪")
 9 
10 # fu() # 这里是获取到生成器对象 generator 不会执行函数
11 print(fu()) # 输出 生成器 generator
12 ret = fu()
13 print(ret.__next__()) # 必须执行__next__()才可以触发生成器的运行 娃哈哈
14 print(ret.__next__()) # 必须执行__next__()才可以触发生成器的运行 美滋滋
15 print(ret.__next__()) # StopIteration 迭代器 找不到 yield 报错
# 生成器的用法和迭代器基本一致
# __next__() 开始执行生成器 . 执行到yield. 直到没有yield. 抛出StopIteration


# 生成器函数有什么用
# 省内存
 1 # 如定制一万衣服 一次性全输出了 全堆到公司没地放
 2 # 普通程序会很占内存
 3 # def buy():
 4 #     lis = []
 5 #     for  i in range(10000):
 6 #         lis.append("衣服%s"%i)
 7 #     return lis
 8 #
 9 # print(buy())
10 
11 # 生成器 要多少拿多少
12 # 省内存
13 # def buy():
14 #     lis = []
15 #     for i in range(1,10000):
16 #         lis.append("衣服%s"%i)
17 #         if i % 50 == 0: # 50一批次得拿
18 #             yield lis
19 #             lis = []  # 每次生成一个新列表(新批次)
20 #
21 # set = buy()  # 获取到生成器
22 # print(set.__next__()) # 拿到第一批1-50
23 # print(set.__next__()) # 拿到第二批51-100
24 # print(set.__next__())
25 # print(set.__next__())
# 生成器还可以用 __next__()  snd()来访问生成器
# send()给上一个yield位置 传值
 1 def food():
 2     print("水饺")
 3     a = yield "大馅水饺"
 4     print("a=", a)
 5     print("烧饼")
 6     b = yield "武大郎烧饼"
 7     print("b=", b)
 8     print("老婆饼")
 9     c = yield "只要老婆不要饼"
10     print("c=", c)
11 
12 # 使用__next__()来访问生成器
13 ret = food() # 生成器
14 # print(ret.__next__())  # 执行第一个yield 水饺 大馅水饺
15 # print(ret.__next__())  # 执行第二个yield 烧饼 武大郎烧饼
16 # print(ret.__next__())  # 执行第三个yield 老婆饼 只要老婆不要饼
17 
18 # 使用 send()来访问生成器 # send()有__next__的作用 但还会返回值给 yield
19 print("返回值是:",ret.__next__())
20 print("返回值是:",ret.send("来两盘")) #  给第一个 a 和__next__()一样也是向下找yield. 但还给上一个yield传值
21 print("返回值是:",ret.send("来五张")) # 返回给了第2个 yield 即b
22 print("返回值是:",ret.send("来一堆!")) # 返回给了第3个 yield 即c
23 
24 #  send()不可以在第一个位置和最后一个位置出现
25 #  最后的yield后的代码是可以执行的但是会报错. StopIteration
# 生成器函数里不要写return
1 def  func():
2     print("哈哈")
3     yield  "呵呵"
4     print("吼吼")
5     return  "嘻嘻" # don't do this!
6 
7 gen = func()
8 gen.__next__()
9 gen.__next__()
# 列表推导式
# 语法 [结果 for循环 if判断]
# 要得到的效果必须放前面的结果位置
 1 lis = ["运动会%s期"% i for i in range(0,18)]
 2 print(lis)
 3 
 4 lis1 = [i for i in range(0,21) if i%2==1]
 5 print(lis1)
 6 
 7 lst = ["中岛美雪", "夏川美里", "原由子", "汪峰", "田震","那英","周杰伦"]
 8 
 9 lst1 = [i for i in lst if len(i)== 2 ]
10 print(lst1)
11 
12 lis = [i**2 for i in range(1,21) if i%2==1]
13 print(lis)
 1 # 已知(3,6,9)
 2 # 输出(1,2,3) (4,5,6) (7,8,9)
 3 #
 4 lis = [3,6,9]
 5 lis1 = []
 6 for i in lis:
 7     lis1.append((i-2,i-1,i))
 8 print(lis1)
 9 
10 # 用推导式
11 lis1 = [(i-2,i-1,i) for i in lis]
12 print(lis1)
13 
14 names = [['Tom', 'Billy', 'Jefferson', 'Andrew', 'Wesley', 'Steven','Joe'],
15         ['Alice', 'Jill', 'Ana', 'Wendy', 'Jennifer', 'Sherry', 'Eva']]
16 
17 for i in names:
18     for j in i:
19         if j.count("e")==2:
20             print(j)
21 # 推导式
22 name1 = [j  for i in names  for j in i  if j.count("e") == 2]
23 print(name1)
# 字典推导式
# 语法 {结果 for循环 if判断}
#
1 # dic = {"张无忌":"赵敏", "杨过":"小龙女", "郭靖":"黄蓉"}
2 # dic1 = {dic[i]:i for i in dic}
3 # print(dic1)
4 #
# 集合推导式  # 不可变 不重复 无序的
# {结果 for循环 if判断}
# set = {i*坚挺 for i in range(1,11)}




# 生成器表达式
# 语法 (结果 for循环 if判断) # 没有元祖推导式!
# 特点: 本质是迭代器 __next__()
# 省内存
# 惰性机制
# 只能往前



 1 # 坑(面试题)生成器函数
 2 def fun():
 3     print(111)
 4     yield 222
 5 
 6 g = fun()
 7 g1 = (i for i in g)  # 没有__next__() 不执行
 8 g2 = (i for i in g1)
 9 
10 print(list(g))
11 print(list(g1))
12 print(list(g2))

猜你喜欢

转载自www.cnblogs.com/xi1419/p/9893356.html