Enfrentando MemoryError en Python

Escribí un programa para encontrar factores primos de un número. Cuando doy un número grande (600851475143) como entrada, aparece MemoryError. A continuación se muestra el código:

def fact(a): factors = [] for i in range(1,a+1): if a%i == 0: factors.append(i) return factors num = raw_input(">> ") #600851475143 a = b = [] a = fact(long(num)) for i in range(0,len(a)): b = fact(a[i]) if len(b) <= 2: print a[i] 

Al navegar, supe que Python hace uso de la memoria de la computadora – RAM. Estoy usando Python en Unbuntu sin cambiar su configuración. ¿Debo cambiar algo para que funcione en una máquina de 64 bits? ¿O debería usar alguna función adicional para evitar este error?

Comentarios

  • Su problema básico es que su algoritmo probablemente esté usando demasiado memoria. Si está utilizando Python 2, entonces range(1, a+1) está intentando crear una lista con 600851475143 elementos. Probablemente esto no sea lo que desea, ya que cada elemento será un número entero y cada número entero ocupa 4 bytes. (Además, esta pregunta no es ' t apropiada para los programadores, ya que realmente necesita una revisión del código y comprender en particular cómo funciona Python).
  • (Probablemente desee xrange, que es un generador que devuelve elementos al bucle for según sea necesario. Sin embargo, puede que ese no sea el único problema .)
  • Su lista tiene 2,2 TB de tamaño. Cambiar a una máquina de 64 bits no ayudará. Necesita instalar más de 2 TB de RAM (que para ser justos requerirá un sistema operativo de 64 bits para usar). O reconsidere su algoritmo.
  • Además de los problemas de memoria (solo porque nadie lo ha señalado hasta ahora), existen algunos algoritmos más eficientes para calcular la lista de factores de un número, o para decidir si un número es primo o para generar una lista de números primos. Si bien la mayoría de la gente habla de complejidad temporal , también existe el concepto relacionado de complejidad espacial .

Responder

Hay varias formas de medir la memoria utilizada por su programa, y es posible que pueda aumentar límites por usuario o algo así.

Sin embargo, no es necesario que asigne esa memoria en primer lugar, ya que puede generar la secuencia sin almacenarla toda:

def fact(a): "just return a generator for the sequence you want" return (i for i in xrange(1,a+1) if a % i == 0) 

Tenga en cuenta que también puede iterar directamente sobre secuencias sin necesidad de indexarlas repetidamente:

for b in fact(long(num)): print b 

Comentarios

  • La lista en la pregunta es 2.2TB grande, dudo que aumentar los límites de recursos ayude 😀
  • Bueno, tal vez el OP pueda esperar hasta 2035, cuando SIMMS de 8 TB están disponibles.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *