面试题-闭包函数以及作用域2
题目:
def add(n, i):
return n+i
def text():
for i in range(4):
yield i
g = text()
for n in [1, 10]:
g = (add(n, i) for i in g)
print(list(g))
[20,21,22,23]
为什么呢?
分析:
生成器函数和生成器表达式都有一个特性,只要你不找它取值(_next_)它就不执行.
函数从上到下开始执行,一直到最后一行之前都没开始,最后list()函数找g要值,上面的生成器表达式才开始执行,我们将循环拆开:
n = 1
g = (add(n,i) for i in g)
n = 10
g = (add(n,i) for i in g)
此时n因为定义顺序,n一定是10,g从下往上找,一个找一个,可以合并起来写成:
n = 10
g = (add(n, i) for i in (add(n, i) for i in [0, 1, 2, 3]))
# 从里面往外面执行,
test() == (0,1,2,3)
(add(n,i) for i in test()) == (10,11,12,13)
(add(n,i) for i in (add(n,i) for i in test())) == (20,21,22,23)
# 结果也就是
g=(20, 21, 22, 23)
结论:
这个for循环中的元素,只有最后一个是真正定义了的,其他的都只是增加循环的次数而已。
不管你填什么,都只是增加循环次数,内容是什么都无所谓,另外只要在最下面再加一个定义,就可以破开这些稀奇古怪的东西