La comprensión de la lista de Python sobrepasa el valor

Eche un vistazo a la siguiente pieza de código, que muestra una lista de comprensión.

>>> i = 6 >>> s = [i * i for i in range(100)] >>> print(i) 

Cuando ejecutas el ejemplo de código en Python 2.6, se imprime 99 , pero cuando lo ejecutas en Python 3.x se imprime 6 .

¿Cuál fue la razón para cambiar el comportamiento y por qué la salida 6 en Python 3.x ?

¡Gracias de antemano!

El viejo comportamiento fue un error, pero no se pudo arreglar fácilmente ya que algunos códigos se basaron en él.

La variable i dentro de la lista de comprensión debe ser diferente de la que se encuentra en el nivel superior. Lógicamente, debe tener su propio scope que no se extienda fuera de la comprensión, ya que su valor solo tiene sentido dentro de la comprensión. Pero en Python 2.x debido a un detalle de implementación, el scope fue más grande de lo necesario, lo que provocó que la variable se “filtre” hacia el scope externo, lo que provoca los resultados confusos que se ven.

Python 3.0 no fue deliberadamente diseñado para ser compatible con versiones anteriores, por lo que aprovecharon la oportunidad para corregir este comportamiento no deseado.

En Python 2.3 y versiones posteriores, una comprensión de la lista “filtra” las variables de control de cada uno para el contenido que contiene. Sin embargo, este comportamiento está en desuso, y confiar en él no funcionará en Python 3.0

Fuente

Sí, hay una razón, y la razón es que no querían que la variable temporal en una lista de comprensión se filtre en el espacio de nombres externo. Por lo tanto, es un cambio intencional que es el resultado de que las comprensiones de listas ahora son azúcar sintáctica para pasar una expresión de generador a list ().

Ref: PEP3100 .

Mark Byers respondió perfectamente.

sólo como una nota al margen …
en Python 2.x, si cambia sus paréntesis a parens (creando una expresión generadora en lugar de una lista de comprensión), notará que la variable de control no se ha filtrado.

 >>> i = 6 >>> s = (i for i in range(100)) >>> print i 6 

contra

 >>> i = 6 >>> s = [i for i in range(100)] >>> print i 99 

(por supuesto, en Python 3, esto es fijo y la lista de comprensión ya no tiene fugas en las variables de control)

Parece un cambio en el scope para mí.

Confirmé tu resultado en Python 2.6; de hecho, imprime 99, que es el último valor asignado a i en la lista de comprensión.