You either have to capture the variable using default assignments
lambdas_list = [ lambda i=o: i.some_var for o in obj_list ]
or, use closures to capture the variable
lambdas_list = [ (lambda a: lambda: a.some_var)(o) for o in obj_list ]
In both cases the key is to make sure each value in the obj_list list is assigned to a unique scope.
Your solution didn't work because the lexical variable obj
is referenced from the parent scope (the for
).
The default assignment worked because we reference i
from the lambda
scope. We use the default assignment to make "passing" the variable implicit by making it part of the lambda
definition and therefore its scope.
The closure solution works because the variable "passing" is explicit, into the outer lambda
which is immediately executed, thus creating the binding during the list comprehension and and returning the inner lambda
which references that binding. So when the inner lambda
actually executes it will be referencing the binding created in the outer lambda
scope.