Question:
lst = [lambda x: x*i for i in range(4)]res = [m(2) for m in lst]print res
Actual output: [6, 6, 6, 6]
How can I change the output value to [0, 2, 4, 6? As follows:
lst = [lambda x, i=i: x*i for i in range(4)]res = [m(2) for m in lst]print res
This problem involves the knowledge of Python closures and delayed binding (Python scope ).
In Python core programming, closures are defined as follows:
If a variable in the external scope (but not in the global scope) is referenced in an internal function, the internal function is regarded as a closure.
Summary:
1. An embedded Function
2. Reference external function variables
3. Embedded functions returned by external functions
Simple closure example:
def counter(start_at=0): count = [start_at] def incr(): count[0] += 1 return count[0] return incr
The above question can be written as follows:
def func(): fun_list = [] for i in range(4): def foo(x): return x*i fun_list.append(foo) return fun_listfor m in func(): print m(2)
Func () is a list of four functions:
[<Function func at 0x00000000021ce9e8>, <function func at 0x00000000021cea58>, <function func at 0x00000000021ceac8>, <function func at 0x00000000021ceb38>]
When we execute M (2), run it to the internal function Foo (), and find that variable I is not a variable in Foo (), so we look for variable I in the external function func, but now the external for has been completed, and the final I = 3. So every time
Run M (2) and the I value is 3. Therefore, the final result is [6, 6, 6, 6].
After I = I is added to Foo (), that is:
def func(): fun_list = [] for i in range(4): def foo(x, i=i): return x*i fun_list.append(foo) return fun_listfor m in func(): print m(2)
In this way, when the for loop is executed, the value of I (0, 1, 2, 3) has been passed to the Foo () function. At this time, I is already Foo () when the internal variable of the function is run to the Foo () function, it does not go to the external function to find the variable I and runs directly.
X * I (0, 1, 2, 3). Therefore, the final result is [0, 2, 4, 6].
[Lambda X: x * I for I in range (4 )]