def add(a,b):
return a+b
def test():
for r_i in range(4):
yield r_i
g = test()
for n in [2,10,5]:
g = (add(n,i) for i in g)
log(list(g))
观察上面一串代码,分解:
首先可以确定g的初始值为test(),即(0,1,2,3)
然后分解for循环,如下:
n = 2:
g = (add(n,i) for i in g)
n = 10:
g = (add(n,i) for i in g)
n = 5:
g = (add(n,i) for i in g)
当n = 2和n = 10的时候,因为没有取值,所以g没有变化。最后循环在n=5结束,此时取值:
g = (add(n,i) for i in (add(n,i) for i in (add(n,i) for i in g)))
将上面公式中所有n变为5,g此时为(0,1,2,3),导出结果:
[15, 16, 17, 18]
难点1:为什么后面for循环中的g是前面g的值?
example:
n = 2时,g = 20;
n = 10时,g = 20*g
那么,最后的g是不是20乘以前面的值呢?
注意:每一次g都是一个生成式,而不是单纯的数值列表。n = 2时,生成式g需要传入一个g = test()的值,依次类推。
难点2:为什么n=2和n=10时,g的数值没有变化?
生成器值的变化只有导出(__next__),传递参数并改变前一个yield的值(send),和for中默认的next循环导出。
而在n=2和n=10的时候,并没有导出值,导致g一直存在,并进入【难点1】的公式。
生成器的惰性机制,导致只有在取值的时候,值才会代入,否则,只是一串代码。具体,可参考上一篇。
if:
最后的log在for循环内会得到什么结果呢?
for n in [2,10,5]:
g = (add(n,i) for i in g)
log(list(g))
那么又回到上一篇的结论了。当g第一次循环的时候,其数值已经被取走,后面的两次循环g为空值,所以导出结果为:
[2, 3, 4, 5]
[]
[]