Enfrentando MemoryError em Python

Eu escrevi um programa para encontrar fatores primos de um número. Quando eu dou um grande número (600851475143) como entrada, MemoryError aparece. Abaixo está o 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] 

Ao navegar, descobri que o Python faz uso da memória do computador – RAM. Estou usando Python no Unbuntu sem alterar sua configuração. Devo mudar anythig para funcionar em uma máquina de 64 bits. Ou devo usar quaisquer funções adicionais para contornar este erro

Comentários

  • Seu problema básico é que seu algoritmo provavelmente está usando muito memória. Se você estiver usando o python 2, range(1, a+1) está tentando criar uma lista com 600851475143 elementos. Provavelmente não é isso que você deseja, pois cada elemento será um número inteiro e cada número inteiro terá 4 bytes. (Além disso, esta questão não é ' t apropriada para programadores, pois você realmente precisa de uma revisão de código e entender em particular como funciona o python.)
  • (Você provavelmente deseja xrange, que é um gerador que retorna elementos para o loop for conforme necessário. Esse pode não ser o único problema que você está tendo, no entanto .)
  • Sua lista tem 2,2 TB. Mudar para uma máquina de 64 bits não ajudará. Você precisa instalar mais de 2 TB de RAM (o que para ser justo exigirá um sistema operacional de 64 bits). Ou repense seu algoritmo.
  • Além dos problemas de memória (só porque nenhum outro apontou até agora), existem alguns algoritmos mais eficientes para calcular a lista de fatores de um número, ou para decidir se um número é primo ou para gerar uma lista de números primos. Enquanto a maioria das pessoas fala sobre complexidade de tempo , há também o conceito relacionado de complexidade de espaço .

Resposta

Existem várias maneiras de medir a memória usada pelo seu programa, e você pode aumentar limites por usuário ou algo assim.

No entanto, você não precisa alocar essa memória em primeiro lugar, já que pode apenas gerar a sequência sem armazenar tudo:

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) 

Observe que você também pode iterar diretamente sobre as sequências sem precisar indexá-las repetidamente:

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

Comentários

  • A lista na questão tem 2,2 TB, duvido que aumentar os limites de recursos ajude 😀
  • Bem, talvez o OP possa esperar até 2035, quando SIMMS de 8 TB estão disponíveis.

Deixe uma resposta

O seu endereço de email não será publicado. Campos obrigatórios marcados com *