生成器;三元表达式, 推导式(表达式)
一, 生成器
1,生成器的本质就是迭代器
2,生成器的特点和迭代器一样.取值方式和迭代器一样(__next__(), send(): 给上一个yield传值).
3,生成器一般由生成器函数或者生成器表达式来创建
4,其实就是手写的迭代器
#只要函数内部包含有yield关键字,那么函数名()的到的结果就是生成器,并且不会执行函数内部代码 def func(): print('====>first') yield 1 print('====>second') yield 2 print('====>third') yield 3 print('====>end') gen= func() # 不会执行你的函数. 拿到的是生成器 print(gen) # <generator object func at 0x0000000002184360> # 函数中如果有yield 这个函数就是生成器函数. 生成器函数() 获取的是生成器. 这个时候不执行函数
# gen.__next__() 执行函数. 执行到下一个yield.
# gen.__next__() 继续执行函数到下一个yield.
yield: 相当于return 可以返回数据.
但是yield不会彻底中断函数. 分段执行函数.可以挂起/保存函数的运行状态
二, 生成器函数
1, 和普通函数没有区别. 里面有yield的函数就是生成器函数.
2, 生成器函数在执行的时候. 默认不会执行函数体. 返回生成器
3,通过生成器的__next__()分段执行这个函数.
4, send() 给上一个yield传值, 不能再开头(没有上一个yield), 最后一个yield也不可以用send()
send() 和__next__()是一样的. 可以执行到下一个yield, 可以给上一个yield位置传值 def func(): print("我是第一个段") a = yield 123 print(a) print("张三是第二段") b = yield 456 print(b) # ?? print("李四是第三段") c = yield 789 print(c) print("王二是最后一个段") yield 79 # 最后收尾一定是yield g = func() print(g.__next__()) # 没有上一个yield 所以不能使用send() 开头必须是__next__() print(g.send("煎饼果子")) print(g.send("韭菜盒子")) print(g.send("锅包肉")) ## ??
# for i in func(): # for的内部一定有__next__()
# print(i)
#
# print(list(func())) # 内部都有__next__()
三, 三元表达式
name=input('姓名>>: ') res='SB' if name == '盖伦' else 'NB' print(res)
四, 推导式
1. 列表推导式 [结果 for循环 条件筛选]
2. 字典推导式 {k:v for循环 条件筛选}
3. 集合推导式 {k for循环 条件}
# 推导式: 用一句话来生成一个列表 lst = ["python"+str(j) for j in range(1,16)] print(lst)
# 100以内能被3整除的数的平方 lst = [i*i for i in range(100) if i%3==0] print(lst)
# [11,22,33,44] => {0:11,1:22,2:33} lst = [11,22,33,44] dic = {i:lst[i] for i in range(len(lst)) if i < 2} # 字典推导式就一行 print(dic)
# 集合推导式 lst = [1, 1, 4, 6,7,4,2,2] s = { el for el in lst } print(s)
五,生成器表达式
(结果 for循环 条件)
特点:
1. 惰性机制
2. 只能向前
3. 节省内存(鸡蛋)
生成器函数 def func(): print(111) yield 222 yield 333 g = func() # 获取生成器 g1 = (i for i in g) # 生成器 g2 = (i for i in g1) # 生成器 #g3 = (i for i in g2) print(list(g)) # ??? [222,333] 源头. 从源头把数据拿走了 print(list(g1)) # ??? [] 这里执行的时候. 源头已经没有数据 print(list(g2)) # ??? [] 这里也没有值了
重难点:
# 求和 def add(a, b): return a + b # 生成器函数 # 0-3 def test(): for r_i in range(4): yield r_i # 0,1,2,3 g = test() # 获取生成器 for n in [2, 10]: g = (add(n, i) for i in g) # g = add(n, i) for i in g 所有n都为最后一个元素 10 print(g) # <generator object <genexpr> at 0x0000000001DF5A40> 还是生产器 # 到最后往里面放数据就对了 print(list(g)) # [20, 21, 22, 23] 带数据n =10算出 n = 2不带值 print(list(g)) # [] 从源头把数据拿走了这里没有为空