[英]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.