Para añadir un poco de claridad (al menos en mi mente)
def makeFun(i): return lambda: i
a = [makeFun(i) for i in range(10)]
b = [lambda: i for i in range(10)]
un makeFun utiliza (i) que es una función con un argumento.
b utiliza lambda: i que es una función sin argumentos.El i que utiliza es muy diferente de la anterior
Para hacer ayb igual podemos hacer ambas funciones a utilizar sin argumentos:
def makeFun(): return lambda: i
a = [makeFun() for i in range(10)]
b = [lambda: i for i in range(10)]
Ahora ambas funciones utilizan el mundial i
>>> a[2]()
9
>>> b[2]()
9
>>> i=13
>>> a[2]()
13
>>> b[2]()
13
O (más útil) que ambos utilizan un argumento:
def makeFun(x): return lambda: x
a = [makeFun(i) for i in range(10)]
b = [lambda x=i: x for i in range(10)]
deliberadamente he cambiado con x donde la variable es local. Ahora :
>>> a[2]()
2
>>> b[2]()
2
éxito!
Ok, ahora esto tiene sentido para mí. ¡Gracias! – Anssi