Variable area inside lambda

Why does this code print "d, d, d, d" and not "a, b, c, d"? How to change it to print "a, b, c, d"?

cons = []
for i in ['a', 'b', 'c', 'd']: 
    cons.append(lambda: i)  
print ', '.join([fn() for fn in cons])      
+5
source share
4 answers

Oddly enough, this is not a variable scope problem, but the quesiton of the semantics of the python loop for(and python variables).

As you would expect, iinside your lambda, it correctly refers to a variable iin the closest closing area. So far so good.

However, you expect this to mean the following:

for each value in the list ['a', 'b', 'c', 'd']: 
    instantiate a new variable, i, pointing to the current list member
    instantiate a new anonymous function, which returns i
    append this function to cons

This actually happens:

instantiate a new variable i
for each value in the list ['a', 'b', 'c', 'd']: 
    make i refer to the current list member
    instantiate a new anonymous function, which returns i
    append this function to cons

That way, your code adds the same variable ito the list four times - and by the time the loop completes, iit matters 'd'.

, python / , , i append (, , lambda). , , python - , , i 'd' .

+6

, "" ( i) , . , , "i".

+2

, :

cons = []
for i in ['a', 'b', 'c', 'd']: 
    cons.append(lambda i=i: i)  
print ', '.join([fn() for fn in cons])     
+2

"" :

 cons =[lambda i= i:i for i in ['a', 'b', 'c', 'd']]   
 print ', '.join([fn() for fn in cons])     
0

All Articles