3

Why in python

[f() for f in [lambda: d for d in [1,2]]]

gives

[2, 2]

Why result differ from another languages (where result is [1,2] as expected)? There are some reasonable reasons for such non-obvious behavior?

martineau
  • 112,593
  • 23
  • 157
  • 280
kakabomba
  • 312
  • 2
  • 8
  • Scope of parameters maybe? Need a closure to preserve previous values. Possibly duplicate of [Scope of python lambda functions and their parameters](http://stackoverflow.com/questions/938429/scope-of-python-lambda-functions-and-their-parameters) – Dilettant Jan 30 '17 at 10:26

1 Answers1

4

In this [lambda d: for d in [1,2]] what you have is

"Running d from 1 to 2, give me a function returning the value of d at the moment when the function is called."

After that list of two functions is constructed, you call [f() for f in that list]. At the moment the function is called, d in [1,2] has already completed, and d has its final value, 2. So both functions return 2.

One way to get a different result is to copy d to a variable for each lambda function you create. The easiest way to do that is:

[f() for f in [lambda x=d: x for d in [1,2]]]

Here each lambda has its own default value for x, which is d at the time the function is created.

khelwood
  • 52,115
  • 13
  • 74
  • 94
  • Only seconds later ;-) +1 – Dilettant Jan 30 '17 at 10:27
  • Yes, thanks. My main question is _why_ not _how_ it works. I only know that reason can be related to mysterious phrase _lexical scope_ – kakabomba Jan 30 '17 at 10:42
  • When you create a lambda function referencing a local variable, it doesn't make a copy of that variable for the lambda function to use; it references the named variable. In this case, that named variable definitely has the value `2` at the point when your lambda functions are called. Or put another way, your two lambda functions are identical: they both return the same variable, `d`. So why would they have different behaviours? – khelwood Jan 30 '17 at 10:59