+ 4
Why does the following code outputs 222 instead of 012?
def cm(): return [lambda x:x*i for I in range(3)] for m in cm(): print(m(1), end="")
7 Réponses
+ 12
Let me rewrite the function regular style.
def cm():
def f(x):
return x*i
l = []
for i in range(3):
l.append(f)
# i is 2 now
return l
The inner function f accesses i, but there is no i. So it has to get i from outside, from cm.
But the function f will be returned from cm, and then cm has already ended.
Now the i, which f is referring to, is lost.
For this purpose, f has a special box __closure__ that 'remembers' the value i from cm.
So f, exported three times within l to the outermost scope, accesses the last value it remembers from when i still existed.
And that was 2.
+ 5
https://docs.python.org/3/faq/programming.html#why-do-lambdas-defined-in-a-loop-with-different-values-all-return-the-same-result
+ 5
These are my thoughts about this program:
Function cm returns a list, containing the function cm, local variables, a list comprehension and a lambda function. As cm runs in a loop controlled by a range object, the returned list contains this information 3 times, each having an individual object id:
if you store the returned "values" in a variable res, you can see what happens:
>>> res = cm)
<class 'list'>
>>> res
[<function cm.<locals>.<listcomp>.<lambda> at 0x66bb7c4>,
<function cm.<locals>.<listcomp>.<lambda> at 0x66bb41c>,
<function cm.<locals>.<listcomp>.<lambda> at 0x66bb2fc>]
>>> res[0](1)
2
>>> res[1](1)
2
>>> res[2](1)
2
The calculated values returned by the lamba function depends on the max value of the range object and the value passed to the lambda function. The function cm uses only the last calculated value, which is 2 in our case and repaeted it 3 times. You can play around this by changing the max value of the range object, and / or the value passed to the function cm
+ 1
“Closure [...] refers to values needed by the function but are taken from the surrounding scope.”
https://stackoverflow.com/questions/14413946/what-exactly-is-contained-within-a-obj-closure
+ 1
HonFu thank you
0
Jan Markus, can you please explain where the fault in code is?
0
Sudden Lee Thank you so much, official answers are so precious.