简体   繁体   English

Lambda和列表理解

[英]Lambdas and list comprehension

I'm trying to understand what's different about the following dictionaries, as they produce different results when passed as arguments into a third-party library's function. 我试图了解以下字典的不同之处,因为当将它们作为参数传递给第三方库的函数时,它们会产生不同的结果。

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

From my understanding, all three dictionaries should be identical but inspecting the variables reveals different function types for each: 根据我的理解,所有三个字典应该相同,但是检查变量会发现每种字典的功能类型不同:

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

As far as my use-case, only the d3 implementation works (meaning I can't take a more dynamic approach without doing something horrifying with exec ). 就我的用例而言,只有d3实现有效(这意味着如果不对exec做一些令人恐惧的事情,我将无法采用更动态的方法)。 Can someone help me understand the difference between these three types of lambdas? 有人可以帮助我了解这三种Lambda之间的区别吗?

Edit 编辑

After everyone's help understanding scoping better, I was able to get my code to run by including the variable as a keyword arg in the function: 在每个人的帮助下更好地了解作用域之后,我可以通过将变量作为关键字arg包含在函数中来使我的代码运行:

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

As suggested by the FAQ page: https://docs.python.org/3/faq/programming.html#why-do-lambdas-defined-in-a-loop-with-different-values-all-return-the-same-result 如常见问题页面所建议: https : //docs.python.org/3/faq/programming.html#why-do-lambdas-defined-in-a-loop-with-different-values-all-return-the -same-结果

Distinct lambdas don't compare equal to each other, not even if they do the same thing. 不同的lambda彼此之间并不相等,即使它们做相同的事情也是如此。 Therefore, objects containing those lambdas will also compare unequal. 因此,包含这些lambda的对象也将比较不相等。

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

As to why the first two versions don't work, it's because when i is captured it's the variable i , not its current value. 至于为什么前两个版本不起作用,是因为当i被捕获时,它是变量 i ,而不是它的当前值。 The lambdas aren't tied to a frozen value of i during the current iteration but rather the variable itself, which changes in successive loop iterations. Lambda不在当前迭代期间绑定到i的冻结值,而是绑定到变量本身,该变量在连续的循环迭代中发生变化。

See also: 也可以看看:

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM