【python】生成器和生成器函数
2020-12-24 09:28
标签:nbsp 第一个 韭菜 == fun 内容 执行 soft 传值 1、生成器函数: 普通函数: def func(): print("周杰伦") return "昆凌" func() #执行func()函数,"周杰伦" print(func()) #执行结果:昆凌 生成器函数: def func(): print("周杰伦") yield "昆凌" # 函数中包含了yield, 当前这个函数就不再是普通的函数了. 是生成器函数 func() #通过func()函数生成一个生成器,非执行,没结果 print(func()) #打印的是该生成器函数所在的内存地址 #return 和yield的区别: return: 执行到return时函数结束执行 yield:函数分段执行,从(当前yield到下一个yield]的内容 举例: def func(): print("周杰伦") yield "昆凌" print("王力宏") yield "李云迪" #print("大家好才是真的好") #最后一个yield后不要写东西,因为__next__()找不到下一个yield时会报错StopIteration g=func() #生成一个生成器 print(g.__next__()) #周杰伦 昆凌 print(g.__next__()) #王力宏 李云迪 2、send() #__next__()和send()区别: __next__() 可以让生成器向下执行一次; send() 也可以让生成器向下执行一次, 给上一个yield传一个值, 第一个和最后一个yield不需要传值(最后一个值可以传进去但会报错)。 举例1: 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) 执行结果: 我吃什么啊 馒头--------------第一次__next__()获取的内容 a= 胡辣汤----第一次send赋值,并打印 大饼-------第一次send获取的内容 b= 狗粮---第二次send赋值 韭菜盒子---第二次send获取的内容 c= 猫粮 GAME OVER 举例2: def func(): print(‘0‘) yield 1 print(‘2‘) yield 3 yield 4 g1 = func() lst = list(g1) #把生成器转换成列表 print(lst) 执行结果: 0 2 [1, 3, 4] 3、列表推倒式 语法:[最终结果 for 变量 in 可迭代对象 if 条件] lst = [i for i in range(1,101) if i%2==0] print(lst) 4、生成器表达式 #生成器表达式和列表推倒式基本是一样的,只是把[]换成() 语法:(最终结果 for 变量 in 可迭代对象 if 条件) g = (i for i in range(10)) print(g) #打印的是通过表达式生成的生成器所在的内存地址 print(g.__next__()) #获取的第一个元素是0 print(list(g)) #获取的是列表 [0,1,2,3,4,5,6,7,8,9] 5、其他推倒式 5.1 字典推倒式: 语法:[结果(key:value) for 变量 in 可迭代对象 if 筛选] #把字典中的key:value互换 .{"b":"a", "d":"c"} dic = {"a":"b", "c":"d"} new_dic = {dic[key]:key for key in dic} print(new_dic) 5.2 集合推倒式: 语法:{结果(key) for 变量 in 可迭代对象 if 筛选} lst = ["马化腾", "马化腾", "王建忠", "张建忠", "张雪峰", "张雪峰"] s = {i for i in lst} # 集合推倒式,无序且不重复,自动去重 print(s) 注:没有元组推倒式(因为元组不可变,小括号括起来的是生成器表达式) 总结: 1、生成器的本质就是迭代器 2、生成器3种生成方法: 1)通过生成器函数 2)通过生成器表达式 3)通过数据转换 3、生成器函数被执行,如func()是拿到一个生成器函数,不是获取里面的内容 4、生成器取值: 1)__next__() 2)send() 3)for循环 4)list(g) 5、return 和yield的区别: return: 执行到return时函数结束执行 yield:函数分段执行,从(当前yield到下一个yield]的内容 6、生成器惰性机制应用 举例1: def func(): print(111) yield 222 g = func() #生成器g g1 = (i for i in g) #生成器g1,但数据来源g g2 = (i for i in g1)#生成器g2,但数据来源g1 print(list(g)) #获取生成器g数据,此时func()才会被执行,打印111,获取到222 print(list(g1))#获取g1数据,来源g,但g数据已被取完,所以返回是空 print(list(g2))#同g1 执行结果: 111 [222] [] [] 举例2:若把print(list(g))注释了,得到的结果怎样? def func(): print(111) yield 222 g = func() #生成器g g1 = (i for i in g) #生成器g1,但数据来源g g2 = (i for i in g1)#生成器g2,但数据来源g1 #print(list(g)) print(list(g1)) print(list(g2)) 执行结果: 111 [222] [] 举例3: def add(a,b): return a + b def test(): for i in range(4): yield i g = test() #0,1,2,3, for n in [2,10]: #n 取值2,10 表示共循环2次 g=(add(n,i) for i in g) print(list(g)) #list(g)时才会执行,生成器惰性特质 #g=(add(n,i) for i in g) 循环2次,相当于最后g=(add(n,i) for i in (add(n,i) for i in g)) #g=(add(n,i) for i in (add(n,i) for i in (0,1,2,3))) #生成器不到最后不执行,最后一次n=10,那么g=(add(10,i) for i in (10,11,12,13)) #g=[20,21,22,23] 【python】生成器和生成器函数 标签:nbsp 第一个 韭菜 == fun 内容 执行 soft 传值 原文地址:https://www.cnblogs.com/xlzhangq/p/13211155.html
上一篇:常用排序算法
下一篇:Java学习(十三)