最近做某公司的数据挖掘岗的笔试题 遇到一道python题 让我印象深刻。如下
def num(): return [lambda x:x*i for i in range(4)] print([m(?) for m in num()])
如果打印的结果为[6,6,6,6] 问❓处的数字应该为多少
分析首先 很显然的 num()函数返回的是4个匿名函数组成的列表 那么遍历这4个函数并调用的结果就是我们的打印结果。如果不仔细想清楚 会很自然的认为答案就是[0*❓,1*❓,2*❓,3*❓]。但是如果是这样 那么无论❓处输入什么数字 结果都不是[6,6,6,6]。这也是我当时第一眼的想法。但是 如果我们我们再仔细想一想 就会发现num()函数内部构成闭包 我们可以将其改写为如下更易懂的形式。
def num(): func_li [] for i in range(4): def func(x): return x*i func_li.append(func) return func_li # 真正的执行 for func in num(): print(func(❓))
在我们调用num()中的每个func()时 func()才开始去寻找需要的参数i,因为函数内部根本找不到i这个变量 但是这个时候 内部的for循环结束 此时存在变量i 3,因此对于调用每个func()来说 返回的结果都是x*3。当明白这个点之后 这个问题也就迎刃而解了 ❓处的数字自然就是2。
如果我们希望当❓处数字为2时 输出的结果是[0,2,4,6],那么可以将num()修改为如下
def num(): return [lambda x,i i:x*i for i in range(4)]
即让每个函数都存储当前for循环的i值。



