In his writeup on Python programming mistakes, Martin Chikilian includes the following to illustrate misconceptions regarding variable lifetimes inside closures:
def create_multipliers():
return [lambda x: i * x for i in range(5)]
for multiplier in create_multipliers():
print(multiplier(2))
The output is understandably surprising to some as i
maintains its final value (4) in the closure between calls to multiplier
. Martin includes a hack to get the desired output (please see his article for details).
What I'm wondering about is what is being accomplished by including the entire lambda
in the list comprehension? Is it a common idiom in some field such as scientific computing? Because, to me, the following is much easier to understand:
def create_multiplier():
return lambda x: [i * x for i in range(5)]
multiplier = create_multiplier()
print(multiplier(2))
Output: [0, 2, 4, 6, 8]
The output from the 2nd version roughly matches that listed as desirable by Martin. So what's going on here?