Lambda和列表理解

时间:2019-03-14 21:16:10

标签: python

我试图了解以下字典的不同之处,因为当将它们作为参数传递给第三方库的函数时,它们会产生不同的结果。

x = list(range(50))
y = list(range(50))

vars = [x, y]

d = [{'func': lambda z: vars[i]} for i in range(len(vars))]
d2 = list({'func': lambda z: vars[i]} for i in range(len(vars)))
d3 = [{'func': lambda z: vars[0]}, {'func': lambda z: vars[1]}]

print(d == d2)  # False
print(d == d3)  # False
print(d2 == d3)  # False

根据我的理解,所有三个字典应该相同,但是检查变量会发现每个字典的函数类型不同:

d -> function <listcomp>.<lambda>
d2 -> function <genexpr>.<lambda>
d3 -> function <lambda>

就我的用例而言,只有d3实现有效(这意味着如果不使用exec做些令人恐惧的事情,我将无法采用更动态的方法)。有人可以帮助我了解这三种类型的Lambda之间的区别吗?

修改

在每个人的帮助下更好地了解作用域之后,通过将变量作为关键字arg包含在函数中,我得以使代码运行:

d = [{'func': lambda x, z=vars[i]: z * x} for i in range(len(vars))]

常见问题解答页面建议:https://docs.python.org/3/faq/programming.html#why-do-lambdas-defined-in-a-loop-with-different-values-all-return-the-same-result

1 个答案:

答案 0 :(得分:4)

不同的lambda彼此之间并不相等,即使它们做相同的事情也是如此。因此,包含这些lambda的对象也将比较不相等。

>>> f1 = lambda z: vars[i]
>>> f2 = lambda z: vars[i]
>>> f1 == f2
False

为什么前两个版本不起作用,这是因为捕获i时它是变量 i,而不是当前值。在当前迭代过程中,lambda并不与冻结值i绑定,而是与变量本身绑定,该变量在连续的循环迭代中会更改。

另请参见: