11生成器相关及推导式(附内置函数分析图url)
1、生成器:
生成器的本质就是迭代器
生成器的特点和迭代器一样,取值方式也和迭代器一样(__next__(),send():给上一个yield传值)
生成器一般由生成器函数或者生成器表达式来创建
其实就是手写的迭代器
2、生成器函数
和普通函数没有区别,函数里面由yield的函数的就是生成器函数
生成器函数在执行的时候,默认不会执行函数体,而是返回生成器,通过生成器的__next__()分段来执行这个函数
send():给上一个yield传值,不能在开头(没有上一次yield),同作一个yield也不能用send()
3、推导式
1、列表推导式[结果 for循环 条件筛选]
2、字典推导式{k:v for循环 条件筛选}
3、集合推导式{k for循环 条件筛选}
4、生成器表达式
# 没有元祖推导式,所以用小括号的就是生成器表达式。
(结果 for循环 条件筛选)
特点:
1、惰性机制
2、只能向前
3、节省内存
通过下面两个例子加深理解:
1 def func(): 2 print(111) 3 yield 222 4 5 6 g = func() 7 g1 = (i for i in g) 8 g2 = (i for i in g1) 9 10 print(list(g)) # [222]这里把源头func的数据拿走了 11 print(list(g1)) # 所以从这里开始,源头已经没有数据了 12 print(list(g2))
1 # 求和函数 2 def add(a, b): 3 return a+b 4 5 6 # 生成器函数 0-3 7 def test(): 8 for r_i in range(4): 9 yield r_i 10 11 12 g = test() 13 14 for n in [2, 10]: # next,find,list 还有for循环函数名这几种方法才会拿值,这里没有拿值 15 g = (add(n, i) for i in g) 16 print(list(g)) 17 18 # ---------------------------------- 19 ''' 20 解题思路: 21 1、拆分循环: 22 for n in [2, 10]: 23 g = (add(n, i) for i in g) 24 可以拆分为: 25 n = 2 26 g = (add(n, i) for i in g) 27 n = 10 28 g = (add(n, i) for i in g) 29 变形可得 30 n = 10 31 g = (add(n, i) for i in (add(n, i) for i in g)) 32 2、仔细审题: 33 这里for循环g并没有取值。直到最后的list(g)才开始拿值。 34 g = 0,1,2,3和n = 10带入上述表达式.如g=0 35 g = (10+i for i in (10+i for i in 0)) 36 g = 20 37 故最后结果为20,21,22,23 38 3、注:为什么要变形? 39 需要理解的是,n=2时,这个时候表达式的n并不会把值代入进去,因为g并没有取值。所以n=10时,需要代入的是上面的表达式,而不是一个 40 计算出来的结果。变形可以方便理解。 41 4、核心考点:惰性机制。不到最后不会拿值 42 '''