通过列表理解定义多个函数的奇怪行为

时间:2012-12-11 15:36:06

标签: python loops user-defined-functions

  

可能重复:
  What do (lambda) function closures capture in Python?

使用此代码:

def problem():
    PHI_LIST_0 = [lambda a, b: a+b+u for u in xrange(3)]
    PHI_LIST_1 = [lambda a, b: a+b+0, lambda a, b: a+b+1, lambda a, b: a+b+2]

    for phi in PHI_LIST_0: print "v0:", phi(1,1)
    print
    for phi in PHI_LIST_1: print "v1:", phi(1,1)

if __name__ == '__main__':
    problem()

我明白了:

v0: 4
v0: 4
v0: 4

v1: 2
v1: 3
v1: 4

预期的行为是最后一个,PHI_LIST_1。我想我理解为什么结果与PHI_LIST_0不同:可能是因为Python使用最后的'u',即2,当phi(1,1)被评估时。

但我想以PHI_LIST_0的定义方式声明一个函数列表,并具有列表推导。有谁知道我怎么能这样做?

1 个答案:

答案 0 :(得分:2)

定义函数时,它会在函数体中的自由变量上创建一个闭包。在您的PHI_LIST_0中,这是变量u。它不保留u的值,它保留了对u的名称的引用。调用该函数时,它使用u的当前值。因此,所有函数都引用相同的变量,并且所有函数都看到它的相同(最后)值,因此它们的行为都相同。

您可以使用默认值技巧解决此问题:

PHI_LIST_0 = [lambda a, b, u=u: a+b+u for u in xrange(3)]

现在定义函数时会计算u参数的默认值,并与函数一起存储。