If I make two lists of functions:
def makeFun(i):
return lambda: i
a = [makeFun(i) for i in range(10)]
b = [lambda: i for i in range(10)]
To add some clarity (at least in my mind)
def makeFun(i): return lambda: i
a = [makeFun(i) for i in range(10)]
b = [lambda: i for i in range(10)]
a uses makeFun(i) which is a function with an argument.
b uses lambda: i which is a function without arguments. The i it uses is very different from the previous
To make a and b equal we can make both functions to use no arguments:
def makeFun(): return lambda: i
a = [makeFun() for i in range(10)]
b = [lambda: i for i in range(10)]
Now both functions use the global i
>>> a[2]()
9
>>> b[2]()
9
>>> i=13
>>> a[2]()
13
>>> b[2]()
13
Or (more useful) make both use one argument:
def makeFun(x): return lambda: x
a = [makeFun(i) for i in range(10)]
b = [lambda x=i: x for i in range(10)]
I deliberately changed i with x where the variable is local. Now:
>>> a[2]()
2
>>> b[2]()
2
Success !