一.生成器
生成器的本质就是迭代器 一个一个的创建对象
1.创建生成器的方式:
1.生成器函数
2.通过生成器表达式来获取生成器
3.类型转换
2.优点
节省内存 ,生成器本身就是代码,几乎不占用内存
3.特点
惰性机制,只能向前,不能反复
二.生成器函数
函数中包含了yield 这个函数就是生成器函数
def func(): print("你叫xxx?") yield "alex" print("真的?") yield "真的" print("Are you sure?") yield "那叫我屌丝把" ret = func() # 拿到的是ret生成器 只是产生一个生成器并不是运行 print(ret) # 只能是打印 生成器的地址 print(ret.__next__()) # 生成器就是迭代器,用next一个一个拿 print(ret.__next__()) print(ret.__next__()) print(ret.__next__()) # 没有下一个了就会出现 StopIteration 错误
1.yield
1.yield和return差不多 yield是分段执行一个函数
return是立即结束这个函数的执行
2.生成器在执行的时候返回生成器,而不是执行执行此函数
2.能向下执行的两个条件
1.__next__ 执行到下一个yield
2.send() 执行到下一个yield,给上一个yield位置传值.在第一次执行生成器的时候不能用send(),最后一个yield也不会传值
def fn(): print("韭菜盒子") a = yield "西红柿炒番茄" print("a",a) b = yield "西红柿炒鸡蛋" print("b",b) c = yield "番茄炒鸡蛋" print("c",c) yield "火烧" gen = fn() # send()可以给上一个yield位置传参 print(gen.__next__()) print(gen.send("番茄")) print(gen.send("西红柿")) print(gen.send("鸡蛋"))
3.获取生成器数据
1.所有生成器都是迭代器都可以使用for循环
2.都可以使用list()函数来获取生成器内所有的数据
4.生成器的记录
生成器中记录的是代码而不是函数的运行
当执行到__next__() 运行此空间中的代码,运行到yield结束
def func(): print("我的天哪 ") yield "宝宝" gen = func() # 创建生成器. 此时运行会把生成器函数中的代码记录在内存
三.推导式
1.列表推导式 [结果 for循环 if]
lst = [ i**2 for i in range(1,101) if i % 2 == 0] print(lst)
2.字典推导式 {结果(k:v) for循环 if}
把字典的键值互换 dic = {"主食": "炒面", "副食": "小拌菜", "汤":"疙瘩汤"} dic1 = { v:k for k,v in dic.items()} print(dic1)
3.集合推导式 {结果(k) for循环 if}
四.生成器表达式
(结果 for循环 if)
g = (i for i in range(10)) #一次性生成器表达式 print(g.__next__()) print(g.__next__()) print(g.__next__()) print(g.__next__()) print(g.__next__()) print(g.__next__()) print(g.__next__()) print(g.__next__()) print(g.__next__()) print(g.__next__()) # 用完就没了 想再次用必须再写一次表达式
五.yield from
def func(): lst = ["衣服%s" %i for i in range(500)] yield from lst # 可以把一个可迭代对象分别进行yield返回 lst1 = ["python%s期" %i for i in range(1,19)] yield from lst1 # 只有上面的yield next完才能轮到第二个 g = func() print(g.__next__()) print(g.__next__())