【Python面试题】下面这段代码的执行结果是什么
def multiply(): return [lambda x: i * x for i in range(4)] print([m(100) for m in multiply()]) [300, 300, 300, 300] 上面代码的运行结果很容易被误判为[0, 100, 200, 300]。首先需要注意的是multiply函数用生成式语法返回了一个列表,列表中保存了4个Lambda函数,这4个Lambda函数会返回传入的参数乘以i的结果。需要注意的是这里有闭包(closure)现象,multiply函数中的局部变量i的生命周期被延展了,由于i最终的值是3,所以通过m(100)调列表中的Lambda函数时会返回300,而且4个调用都是如此。 如果想得到[0, 100, 200, 300]这个结果,可以按照下面几种方式来修改multiply函数。
方法一:使用生成器,让函数获得i的当前值。def multiply(): return (lambda x: i * x for i in range(4)) print([m(100) for m in multiply()]) def multiply(): for i in range(4): yield lambda x: x * i print([m(100) for m in multiply()])
方法二:使用偏函数,彻底避开闭包现象。 from functools import partial from operator import __mul__ def multiply(): return [partial(__mul__, i) for i in range(4)] print([m(100) for m in multiply()])