¿Por qué se puede acceder a la variable de comprensión de la lista después de realizar la operación?

Como parte de otra experiencia, encontré un problema en la lista de comprensión. En pocas palabras, si estoy probando el siguiente código:

m = [ k**2 for k in range(7)] print m [0, 1, 4, 9, 16, 25, 36] print k 6 
  1. Mi pregunta es ¿cómo es que Python puede obtener el valor de k, fuera de la comprensión de la lista?
  2. ¿Por qué no se recoge la basura k?
  3. ¿No es esto una pérdida de memoria?

No, no es una pérdida de memoria, ya que ese término generalmente se define. En Python 2.x, una comprensión de lista no es un ámbito separado, por lo que una variable que use en una comprensión de lista está en el scope de la función que la contiene. Puede verlo fácilmente en acción configurando k antes de la comprensión de la lista; el listcomp lo va a pegar.

Debido a que existe una referencia válida, el objeto al que k apunta no es (correctamente) recogida de basura.

En Python 3.x, esto fue cambiado; todas las comprensiones crean sus propios ámbitos y no se “filtran” en el ámbito de cierre.

En Python 2.x, las expresiones generadoras tienen su propio scope, sin embargo, si quieres ese comportamiento, simplemente escríbelo así:

 m = list(k**2 for k in range(7)) 

Porque en Python 2, la variable de la lista ‘se filtra’ al ámbito circundante. Esto fue un error en la forma en que se construyeron las comprensiones de listas.

Esto se ha corregido para dictados y conjuntos de comprensión, expresiones de generador y en Python 3 para listas de comprensión también.

No es una pérdida de memoria. Es solo un error en el scope de la variable.