Face à MemoryError en Python

Jai écrit un programme pour trouver les facteurs premiers dun nombre. Lorsque je donne un grand nombre (600851475143) comme entrée, MemoryError apparaît. Voici le code:

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] 

En naviguant, jai appris que Python utilise la mémoire de lordinateur – RAM. Jutilise Python dans Unbuntu sans changer sa configuration. Dois-je changer anythig pour travailler sur une machine 64 bits. Ou devrais-je utiliser une ou plusieurs fonctions supplémentaires pour contourner cette erreur

Commentaires

  • Votre problème de base est que votre algorithme en utilise probablement trop Mémoire. Si vous utilisez python 2, alors range(1, a+1) tente de créer une liste avec 600851475143 éléments. Ce nest probablement pas ce que vous voulez car chaque élément sera un entier et chaque entier prend 4 octets. (De plus, cette question nest pas ' t appropriée pour les programmeurs car vous avez vraiment besoin dune révision du code et de comprendre en particulier le fonctionnement de python.)
  • (Vous voulez probablement xrange, qui est un générateur qui renvoie des éléments à la boucle for si nécessaire. Ce nest peut-être pas le seul problème que vous rencontrez, cependant .)
  • Votre liste fait 2,2 To. Passer à une machine 64 bits naidera pas. Vous devez installer plus de 2 To de RAM (ce qui, pour être juste, nécessitera un système dexploitation 64 bits). Ou repensez votre algorithme.
  • En plus des problèmes de mémoire (simplement parce quaucun autre ne la signalé jusquà présent), il existe des algorithmes plus efficaces pour calculer la liste des facteurs dun nombre, ou pour décider si un nombre est premier, ou pour générer une liste de nombres premiers. Alors que la plupart des gens parlent de complexité temporelle , il existe également le concept associé de complexité spatiale .

Réponse

Il existe plusieurs façons de mesurer la mémoire utilisée par votre programme, et vous pourrez peut-être augmenter des limites par utilisateur ou quelque chose.

Cependant, vous n’avez pas besoin d’allouer cette mémoire en premier lieu, car vous pouvez simplement générer la séquence sans tout stocker:

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) 

Notez que vous pouvez également parcourir directement les séquences sans avoir besoin de les indexer à plusieurs reprises:

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

Commentaires

  • La liste dans la question est de 2,2 To, je doute que laugmentation des limites de ressources aidera 😀
  • Eh bien, peut-être que lOP peut attendre 2035, quand 8 To SIMMS sont disponibles.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *