I thought I understood lambda notation (in python) for defining functions, but I'm seeing a strange behavior that I don't understand. I looked at What do (lambda) function closures capture? and saw something that I think is related but isn't the same.
I generate a list of functions inside a function. Inside that function, the behavior of the functions in the list is as expected. However, when it's returned to main(), items 1 through 3 of the list all behave as item 3. I say "behave as" because you can see that the functions aren't actually identical -- they're stored at different memory locations.
I put in some debugging lines that are commented, which help a little in seeing what the code is doing. The lambda function depends on an integer, and the value of the integer is as expected inside the function but is the same for list items 1 through 3 in main().
I'd really appreciate if someone could help me understand what's going on here. Thanks!
import numpy as np
def make_func_list(matA):
size = matA.shape[0]
vec = np.ones(size)
lst_f = []
lst_f.append( lambda x: sum(x) )
for ii in xrange(1,size):
lst_f.append( lambda x: np.dot(matA[ii], x) )
print '-----------------'
print '- in function -'
for ii in xrange(size):
print 'func_list', ii, lst_f[ii](vec)
print lst_f[ii] # note that the memory addresses are different
if ii > 0:
print lst_f[ii].func_closure[0].cell_contents # the integer is different
print '-----------------'
return lst_f
if __name__ == "__main__":
size = 4
matA = np.reshape(np.arange(size**2),(size,size))
vec = np.ones(size)
print "### matA ###"
print matA
func_list = make_func_list(matA)
print '================='
print '= in main() ='
for ii in xrange(len(matA)):
print 'func_list', ii, func_list[ii](vec)
print func_list[ii] # memory addresses are unchanged from in make_func_list()
if ii > 0:
print func_list[ii].func_closure[0].cell_contents # but the integer is the same for all ii
print '================='