La comprensión del diccionario con funciones lambda da resultados incorrectos

Probé el siguiente código en Python 3.5.1:

>>> f = {x: (lambda y: x) for x in range(10)} >>> f[5](3) 9 

Es obvio que esto debería devolver 5 . No entiendo de dónde viene el otro valor, y no pude encontrar nada.

Parece que es algo relacionado con la referencia: siempre devuelve la respuesta de f[9] , que es la última función asignada.

¿Cuál es el error aquí y cómo se debe hacer para que funcione correctamente?

El scope de Python es léxico . Un cierre se referirá al nombre y al scope de la variable, no al objeto / valor real de la variable.

Lo que sucede es que cada lambda está capturando la variable x no el valor de x .

Al final del bucle, la variable x está vinculada a 9, por lo tanto, cada lambda se referirá a esta x cuyo valor es 9.

Por qué funciona la respuesta de @PrisP:

make_func obliga a que se make_func el valor de x (a medida que se pasa a una función). Por lo tanto, la lambda se hace con el valor de x actualmente y evitamos el problema de scope anterior.

 def make_func(x): return lambda y: x f = {x: make_func(x) for x in range(10)} 

Lo siguiente debería funcionar:

 def make_func(x): return lambda y: x f = {x: make_func(x) for x in range(10)} 

La x en su código termina refiriéndose al último valor de x , que es 9 , pero en la mía se refiere a la x en el scope de la función.