I've been trying to create a bunch of lambdas, one for each key in a dictionary, without having to do them one by one. I ended up achieving what I wanted to, but I want to understand why my first approach didn't work, while the second one did. I assumed they would produce the exact same results... I don't see what I'm missing!
I've included a small reprex below:
# approach 1 ========================================
bunch_of_funcs = {
"func1": None,
"func2": None,
"func3": None,
"func4": None,
}
for func_name in bunch_of_funcs:
bunch_of_funcs[func_name] = lambda: print(func_name)
# now executing... prints func4 4 times
for func in bunch_of_funcs.values():
func()
# approach 2 ========================================
def lambda_func(func_name):
return lambda: print(func_name)
for func_name in bunch_of_funcs:
bunch_of_funcs[func_name] = lambda_func(func_name)
# now executing... prints what i expect
for func in bunch_of_funcs.values():
func()
EDIT: After chepner's answer, I tried "localizing" the variable by wrapping the for loop inside of a function. I'm still getting the same result, though... Where is this global variable being created? And why is it being changed on every iteration? My change below:
def make_lambdas(dict_of_funcs):
for func_name in dict_of_funcs:
dict_of_funcs[func_name] = lambda: print(func_name)
make_lambdas(bunch_of_funcs)
In both cases, your lambda-defined function wraps a name func_name
. However, that name refers to two different variables. In the first case, it refers to a single global variable. In the second case, it refers to 4 different local variables, a new one for each call to lambda_func
.