一.生成器    本质就是迭代器. 我们可以直接执⾏__next__()来执⾏ 以下⽣成器 一个一个的创建对象 创建生成器的方式: 1.生成器函数 2.通过生成器 表达式来获取生成器 3.类型转换(看不到) 二.生成器函数(重点)    深坑:生成器在要值得时候才拿值 生成器函数中包含yield,返回数据和return差不多:return会立即结束这个函数的执行,yield 表示返回,不会终止函数的执行,可以分段的执行一个函数. 当函数中包含了yield,次函数就是生成器函数 坑:生成器函数在执行的时候返回生成器.而不是之直接执行此函数 函数中包含了yield, 此函数就是生成器函数 大坑: 生成器函数运行之后. 产生一个生成器. 而不是运行函数 def func():     print("我叫周润发")     yield "林志玲"   # yield表示返回. 不会终止函数的执行     print("宝宝干嘛去了??")     yield "宝宝回来了"     print("宝宝你在干嘛?")     # yield "没了"   ret = func() # 执行函数, 此时没有运行函数.生成器或者迭代器的好处:节省内存 # # 此时我们拿到的是生成器 # print("返回值是", ret) # <generator生成器 object func at 0x0000000009E573B8>   # 执行到下一个yield print(ret.__next__()) # 第一次执行__next__此时函数才开始执行 print(ret.__next__()) # 执行到下一个yield print(ret.__next__()) # StopIteration send()  ----> 同__next__()开始执行 send()可以给上一个yield位置传值 能够向下执行的两个条件:      __next__(),执行到下一个yield      send(),执行到下一个yield,给上一个yield位置传值, send和__next__()区别:  1. send和next()都是让⽣成器向下走⼀次  2. send可以给上⼀个yield的位置传递值, 不能给最后⼀个yield发送值. 在第⼀次执⾏⽣ 成器代码的时候不能使⽤send() def func():     print("韭菜盒子")     a = yield "韭菜鸡蛋"     print("a", a)     b = yield "韭菜西红柿"     print("b", b)     c = yield "火烧"     yield "GAME OVER"   gen = func()   print(gen.__next__()) # 第一个位置用send没有任何意义 print(gen.send("篮球")) # 给上一个yield位置传值  "篮球"这个值赋值给a print(gen.send("足球"))   ##韭菜盒子 韭菜鸡蛋 a 篮球 韭菜西红柿 b 足球 火烧 生成器中记录的是代码而不是函数的运行 def func():             print("我的天哪 ")               yield "宝宝"           gen = func() # 创建生成器.  此时运行会把生成器函数中的代码记录在内存         当执行到__next__(), 运行此空间中的代码, 运行到yield结束.           优点: 节省内存, 生成器本身就是代码. 几乎不占用内存         特点: 惰性机制, 只能向前. 不能反复 三.各种推导式 列表推导式    [结果 for循环 if] #生成列表: python1->python18 lst = [] for i in range(1, 19):     lst.append("python%s期" % i)   print(lst) 列表推导式 [结果 for循环 if条件]     lst = ["python%s期" % i for i in range(1, 19)] print(lst)   #生成列表.类表中装的数据是 1-100之间所有的偶数的平方   lst = [i**2 for i in range(1, 101) if i%2 == 0] print(lst)   #筛选出列表中姓张的同学, lst = ["张无忌", "吴奇隆", "张诗诗", "范冰冰", "张翠山"] lst = ["张无忌", "吴奇隆", "张诗诗", "范冰冰", "张翠山"] lst2 = [name for name in lst if name.startswith("张")] print(lst2)   # 寻找名字中带有两个e的人的名字 names = [['Tom', 'Billy', 'Jefferson', 'Andrew', 'Wesley', 'Steven','Joe'],         ['Alice', 'Jill', 'Ana', 'Wendy', 'Jennifer', 'Sherry', 'Eva']]   lst = [name for el in names for name in el if name.count("e") == 2] print(lst) 字典推导式    {结果(k:v) for循环 if} 字典推导式 语法: { 结果(key:value) for循环 if条件} lst = [11,22,33]  # {0:11, 1:22, 2:33}   dic = {i:lst[i] for i in range(len(lst))} print(dic)   练习: {"主食": "炒面", "副食": "小拌菜", "汤":"疙瘩汤"} 把字典的key和value互换, 生成新字典 dic =  {"主食": "炒面", "副食": "小拌菜", "汤":"疙瘩汤"} d = { v:k for k, v in dic.items()} print(d) 结合推导式    {结果(k) for循环 if} 没有元组推导式 四.生成器表达式(重点) (结果 for循环 if) g = (i for i in range(10)) # 生成器表达式   print(g)  # <generator object <genexpr> at 0x0000000009E573B8>   print(g.__next__()) # 0 print(g.__next__()) # 1 print(g.__next__()) # 2 print(g.__next__()) # 3 print(g.__next__()) # 4 print(g.__next__()) # 5 print(g.__next__()) # 6 print(g.__next__()) # 7 print(g.__next__()) # 8 print(g.__next__()) # 9 # print(g.__next__()) # ??? StopIteration from   可以把一个可迭代对象分别进行yield返回 def func():     lst = ["衣服%s" % i for i in range(500)]     yield from lst # 可以把一个可迭代对象分别进行yield返回       lst1 = ["python%s" % i for i in range(18)]     yield from lst1     gen = func() print(gen.__next__()) print(gen.__next__())
扫码关注我们
微信号:SRE实战
拒绝背锅 运筹帷幄