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
). Can someone help me understand the difference between these three types of lambdas?
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:
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