A MemoryError szembesülése a Pythonban

Programot írtam egy szám prímtényezőinek megkeresésére. Amikor nagy számot (600851475143) adok meg bemenetként, felugrik a MemoryError. Az alábbiakban látható a kód:

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] 

A böngészés során megtudtam, hogy a Python számítógépes memóriát – RAM-ot használ. A Python-ot az Unbuntuban használom anélkül, hogy megváltoztatnám a konfigurációját. Meg kell-e változtatnom bármelyiket úgy, hogy 64 bites gépen működjön. Vagy használjak bármilyen további funkciót a hiba kiküszöbölésére

Megjegyzések

  • Alapvető probléma, hogy az algoritmus valószínűleg túl sokat használ memória. Ha a Python 2 szoftvert használja, akkor az range(1, a+1) megpróbálja létrehozni a 600851475143 elemet tartalmazó listát. Valószínűleg nem ezt akarja, mivel minden elem egész szám lesz, és minden egyes szám 4 bájtot vesz igénybe. (Továbbá, ez a kérdés nem felel meg a programozóknak, mivel valóban szükség van egy kód felülvizsgálatára és különösen a python működésének megértésére.)
  • (Valószínűleg xrange, amely egy generátor, amely szükség szerint elemeket ad vissza a for ciklusba. Lehet, hogy nem ez az egyetlen probléma, bár .)
  • A listád 2,2 TB nagy. A 64 bites gépre váltás nem segít. Több mint 2 TB RAM-ot kell telepítenie (ami igaz, a használatához 64 bites operációs rendszerre lesz szükség). Vagy gondolja át algoritmusát.
  • A memóriaproblémák mellett (csak azért, mert eddig senki nem hívta fel a figyelmet), van néhány hatékonyabb algoritmus a szám tényezőinek listájának kiszámításához vagy a döntéshez hogy egy szám prím-e, vagy a prímszámok listájának létrehozása. Míg a legtöbben az idő bonyolultságáról beszélnek, a tér bonyolultságáról is van szó.

Válasz

A program által használt memória mérésére különféle módok vannak, és növelheti Felhasználónkénti korlátok vagy valami hasonló.

Azonban először nem kell ezt a memóriát lefoglalnia, mivel csak úgy generálhatja a szekvenciát, hogy nem tárolja az egészet:

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) 

Ne feledje, hogy a szekvenciákon is közvetlenül iterálhat anélkül, hogy ismételten indexelnie kellene őket:

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

Megjegyzések

  • A kérdésben szereplő lista 2,2 TB, kétlem, hogy az erőforrás-korlátok emelése segít 😀
  • Nos, talán az OP várhat 2035-ig, amikor 8TB SIMMS érhető el.

Vélemény, hozzászólás?

Az email címet nem tesszük közzé. A kötelező mezőket * karakterrel jelöltük