MemoryErrorin kohtaaminen Pythonissa

Kirjoitin ohjelman löytämään luvun alkutekijät. Kun annan syötteenä suuren määrän (600851475143), MemoryError ponnahtaa esiin. Alla on koodi:

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] 

Selaamisen aikana sain tietää, että Python käyttää tietokoneen muistia – RAM-muistia. Käytän Pythonia Unbuntussa muuttamatta sen kokoonpanoa. Pitäisikö minun vaihtaa mikä tahansa toimimaan 64-bittisessä koneessa. Vai pitäisikö minun käyttää muita toimintoja kiertääksesi tämän virheen?

Kommentit

  • Perusongelmasi on, että algoritmisi käyttää todennäköisesti liikaa muisti. Jos käytät python 2: ta, range(1, a+1) yrittää luoda luettelon 600851475143 elementistä. Tämä ei todennäköisesti ole mitä haluat, koska jokainen elementti on kokonaisluku ja jokainen kokonaisluku vie 4 tavua. (Tämä kysymys ei ole myöskään ' sopiva ohjelmoijille, koska tarvitset todella koodin tarkistuksen ja ymmärrät erityisesti pythonin toiminnan.)
  • (Luultavasti haluat xrange, joka on generaattori, joka palauttaa elementit for -silmukkaan tarpeen mukaan. Se ei kuitenkaan välttämättä ole ainoa ongelma, joka sinulla on .)
  • Luettelosi on 2,2 Tt iso. Siirtyminen 64-bittiseen koneeseen ei auta. Sinun on asennettava yli 2 Tt RAM-muistia (mikä on oikeudenmukaista, tarvitaan 64-bittinen käyttöjärjestelmä). Tai ajattele algoritmiasi uudelleen.
  • Muistiongelmien lisäksi (vain koska kukaan muu ei ole toistaiseksi huomauttanut), on joitain tehokkaampia algoritmeja luvun tekijäluettelon laskemiseksi tai päättämiseksi. onko numero alkuluku, tai luoda luettelo alkulukuista. Vaikka useimmat ihmiset puhuvat ajan monimutkaisuudesta , on olemassa myös siihen liittyvä käsite avaruuden monimutkaisuudesta .

vastaus

Ohjelmasi käyttämän muistin mittaamiseen on useita tapoja, ja voit ehkä lisätä käyttäjäkohtaiset rajoitukset tai jotain.

Sinun ei kuitenkaan tarvitse allokoida sitä muistia, koska voit luoda sarjan vain tallentamatta sitä kaikkea:

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) 

Huomaa, että voit myös toistaa suoraan sekvenssejä tarvitsematta niitä indeksoida toistuvasti:

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

kommentit

  • Kysymyksessä oleva luettelo on 2,2 Tt, epäilen resurssirajojen nostamisesta 😀
  • No, kenties OP voi odottaa vuoteen 2035, jolloin 8 Tt: n SIMMS-koodit ovat käytettävissä.

Vastaa

Sähköpostiosoitettasi ei julkaista. Pakolliset kentät on merkitty *