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
  • 119,623
  • 25
  • 170
  • 301
kakabomba
  • 331
  • 2
  • 10

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
  • 55,782
  • 14
  • 81
  • 108
  • 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