Reputation: 497
Consider this short code snippet:
class X:
pass
xs = []
for s in ("one", "two", "three"):
x = X()
x.f = lambda: print(s)
xs.append(x)
for x in xs:
x.f()
It outputs:
three
three
three
I thought the result should be like this instead:
one
two
three
Why is that not the actual result?
Upvotes: 3
Views: 54
Reputation: 2887
It happens because the s
variable is a reference, not a value. And the value by reference will be resolved when it will be called, not created. To resolve the value in the creation time use the default argument
.
lambda s=s: print(s)
Upvotes: 2
Reputation: 2182
Your lambda function holds reference to s
, hence the last assigned value to s is printed when called outside that for loop. Try the below code for your expected behaviour. Here a copy of that existing reference s
is created in v
as function argument and that value is printed inside the function f
.
class X:
pass
xs = []
for s in ("one", "two", "three"):
x = X()
def f(v=s): print(v)
x.f = f
xs.append(x)
for x in xs:
x.f()
Output:
one
two
three
Upvotes: 2