Geconfronteerd met MemoryError in Python

Ik heb een programma geschreven om priemfactoren van een getal te vinden. Als ik een groot getal (600851475143) als invoer geef, verschijnt MemoryError. Hieronder staat de 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] 

Door te browsen kwam ik erachter dat Python gebruik maakt van computergeheugen – RAM. Ik gebruik Python in Unbuntu zonder de configuratie te wijzigen. Moet ik iets veranderen om op een 64-bits machine te werken. Of moet ik extra functie (s) gebruiken om deze fout te omzeilen

Opmerkingen

  • Uw fundamentele probleem is dat uw algoritme waarschijnlijk te veel gebruikt geheugen. Als je python 2 gebruikt, probeert range(1, a+1) een lijst te maken met 600851475143 elementen. Dit is waarschijnlijk niet wat u wilt, aangezien elk element een geheel getal is en elk geheel getal 4 bytes in beslag neemt. (Deze vraag is ook niet ' t geschikt voor programmeurs, aangezien je echt een codereview nodig hebt en in het bijzonder wilt begrijpen hoe Python werkt.)
  • (Je wilt waarschijnlijk xrange, wat een generator is die elementen naar de for -lus retourneert als dat nodig is. Dat is echter niet het enige probleem dat u ondervindt .)
  • Je lijst is 2,2 TB groot. Overschakelen naar een 64-bits machine zal niet helpen. U moet meer dan 2 TB RAM installeren (wat om eerlijk te zijn vereist een 64-bits besturingssysteem om te gebruiken). Of heroverweeg uw algoritme.
  • Naast geheugenproblemen (alleen omdat anderen er tot nu toe niet op hebben gewezen), zijn er enkele efficiëntere algoritmen voor het berekenen van de lijst met factoren van een getal, of om te beslissen of een getal een priemgetal is, of om een lijst met priemgetallen te genereren. Terwijl de meeste mensen praten over tijdcomplexiteit , is er ook het verwante concept van ruimtecomplexiteit .

Answer

Er zijn verschillende manieren om het geheugen dat door uw programma wordt gebruikt te meten, en u kunt mogelijk limieten per gebruiker of zoiets.

U hoeft dat geheugen in de eerste plaats echter niet toe te wijzen, aangezien u de reeks gewoon kunt genereren zonder alles op te slaan:

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) 

Merk op dat u reeksen ook rechtstreeks kunt herhalen zonder ze herhaaldelijk te hoeven indexeren:

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

Opmerkingen

  • De lijst in de vraag is 2,2 TB groot, ik betwijfel of het verhogen van de resource limieten zal helpen 😀
  • Nou, misschien kan het OP wachten tot 2035, wanneer 8TB SIMMS zijn beschikbaar.

Geef een reactie

Het e-mailadres wordt niet gepubliceerd. Vereiste velden zijn gemarkeerd met *