¿Cuándo borra Python las variables?

Sé que Python tiene un recolector automático de basura, por lo que debería eliminar automáticamente las variables cuando no haya más referencias a ellas.

Mi impresión es que esto no sucede con las variables locales (dentro de una función).

def funz(z): x = f(z) # x is a np.array and contains a lot of data x0 = x[0] y = f(z + 1) # y is a np.array and contains a lot of data y0 = y[0] # is x still available here ? return y[0], x[0] 

es del x la forma correcta de ahorrar memoria?

  def funz(z): x = f(z) # x is a np.array and contains a lot of data x0 = x[0] del x y = f(z + 1) # y is a np.array and contains a lot of data y0 = y[0] return y[0], x[0] 

EDITAR: He editado mi ejemplo de manera que es más similar a mi problema real. En mi problema real, x e y no son una lista sino una clase que contiene diferentes np.array largos

EDITAR: Soy capaz de ejecutar el código:

     x = f(z) x[0] print(x0) y = f(z + 1) y0 = [0] print( y0) 

    Las implementaciones utilizan el recuento de referencias para determinar cuándo se debe eliminar una variable.

    Una vez que la variable quede fuera del scope (como en su ejemplo) si no hay referencias restantes, entonces la memoria se liberará.

     def a(): x = 5 # x is within scope while the function is being executed print x a() # x is now out of scope, has no references and can now be deleted 

    Aparte de las claves del diccionario y los elementos en las listas, generalmente hay muy pocas razones para eliminar manualmente las variables en Python.

    Aunque, como se dijo en las respuestas a esta pregunta , usar del puede ser útil para mostrar la intención.

    Es importante mantener dos conceptos separados: nombres y valores. Una variable en Python es un nombre que se refiere a un valor. Los nombres tienen scope: cuando define una variable local (al asignar un valor a un nombre), el scope de la variable es la función actual. Cuando la función regresa, la variable desaparece. Pero eso no significa que el valor se vaya.

    Los valores no tienen scope: se quedan hasta que no haya más nombres que se refieran a ellos. Puede crear un valor en una función y devolverlo desde esa función, haciendo que un nombre fuera de la función se refiera al valor, y el valor no se reclamará hasta algún punto futuro cuando todas las referencias hayan desaparecido.

    Más detalles (¡incluyendo imágenes!) Están aquí: Hechos y mitos sobre los nombres y valores de Python .

    Escribe cosas que quieras borrar de la memoria en funciones separadas. En tu ejemplo, puedes hacer

      def xdef(z): x = f(z) # x is a np.array and contains a lot of data x0 = x[0] def funz(z): xdef(z) y = f(z + 1) # y is a np.array and contains a lot of data y0 = y[0] return y[0], x[0] 

    Esto causará una excepción.

    Depende de la implementación y del tipo de variable. Para objetos simples como ints hay algunas optimizaciones. En CPython, por ejemplo, un int simple reutilizará la misma memoria, incluso después de que se haya utilizado del. No puedes contar con eso, pero ilustra que las cosas son más complejas de lo que parecen.

    Recuerda que cuando estás eliminando un nombre, no necesariamente un objeto.
    Por ejemplo:

     # x is a np.array and contains a lot of data 

    Sería redactado más exactamente como:

     # x references a np.array which contains a lot of data 

    del decrementará el recuento de referencia en ese objeto, pero incluso cuando se reduce a cero, no se garantiza que se recolecte basura en el corto plazo.

    Te sugiero que mires el módulo gc para una explicación e inspiración. Entonces piensa de nuevo.

    Si se está quedando “sin memoria”, es probable que tenga un problema fundamental con su diseño. Lo más probable es que esté cargando demasiados datos de una vez (¿intenta usar iteradores?), O tal vez su código deba estar mejor estructurado.

    Acabo de ver tu edición. ¿Necesita toda esa matriz en la memoria al mismo tiempo? ¿Podrías usar un generador?

    Otra alternativa es usar una base de datos como SQLite o tal vez un archivador