有办法避免这种内存错误吗? [英] Is there a way to avoid this memory error?

查看:72
本文介绍了有办法避免这种内存错误吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在解决Euler项目上的问题,到目前为止,我已经提出了解决此问题的代码.

I'm currently working through the problems on Project Euler, and so far I've come up with this code for a problem.

from itertools import combinations
import time

def findanums(n):
    l = []
    for i in range(1, n + 1):
        s = []
        for j in range(1, i):
            if i % j == 0:
                s.append(j)
        if sum(s) > i:
            l.append(i)
    return l

start = time.time() #start time

limit = 28123

anums = findanums(limit + 1) #abundant numbers (1..limit)
print "done finding abundants", time.time() - start

pairs = combinations(anums, 2)
print "done finding combinations", time.time() - start

sums = map(lambda x: x[0]+x[1], pairs)
print "done finding all possible sums", time.time() - start

print "start main loop"
answer = 0
for i in range(1,limit+1):
    if i not in sums:
        answer += i
print "ANSWER:",answer

运行此命令时,我遇到了MemoryError.

When I run this I run into a MemoryError.

回溯:

File "test.py", line 20, in <module>
    sums = map(lambda x: x[0]+x[1], pairs)

我试图通过禁用垃圾收集来阻止垃圾收集,但我没有从谷歌那里获得垃圾收集.我是否以错误的方式来处理?在我的脑海中,这感觉是最自然的方式,而此时我感到茫然.

I've tried to prevent it by disabling garbage collection from what I've been able to get from Google but to no avail. Am I approaching this the wrong way? In my head this feels like the most natural way to do it and I'm at a loss at this point.

侧注:我正在使用PyPy 2.0 Beta2(Python 2.7.4),因为它比我使用的任何其他python实现都要快得多,而且Scipy/Numpy令我头疼,因为我仍然才刚刚开始编程,我没有工程学或扎实的数学背景.

SIDE NOTE: I'm using PyPy 2.0 Beta2(Python 2.7.4) because it is so much faster than any other python implementation I've used, and Scipy/Numpy are over my head as I'm still just beginning to program and I don't have an engineering or strong math background.

推荐答案

正如Kevin在评论中提到的那样,您的算法可能是错误的,但是无论如何您的代码都没有得到优化.

As Kevin mention in the comments, your algorithm might be wrong, but anyway your code is not optimized.

当使用非常大的列表时,通常使用generators,有个著名的Stackoverflow出色答案,解释了yieldgenerator的概念-

When using very big lists, it is common to use generators, there is a famous, great Stackoverflow answer explaining the concepts of yield and generator - What does the "yield" keyword do in Python?

问题在于您的pairs = combinations(anums, 2)不会生成generator,而是会生成一个较大的对象,这会消耗更多的内存.

The problem is that your pairs = combinations(anums, 2) doesn't generate a generator, but generates a large object which is much more memory consuming.

我将您的代码更改为具有此功能,因为您只对集合进行了一次迭代,所以您可以懒惰地评估值:

I changed your code to have this function, since you iterating over the collection only once, you can lazy evaluate the values:

def generator_sol(anums1, s):
      for comb in itertools.combinations(anums1, s):
        yield comb

现在而不是pairs = combinations(anums, 2)会生成一个大对象. 使用:

Now instead of pairs = combinations(anums, 2) which generates a large object. Use:

pairs = generator_sol(anums, 2)

然后,我将使用另一个generator:

Then, instead of using the lambda I would use another generator:

sums_sol = (x[0]+x[1] for x in pairs)

另一个提示,您最好查看 xrange 合适的是,它不会生成列表,而是生成一个xrange object,在许多情况下(例如此处),效率更高.

Another tip, you better look at xrange which is more suitable, it doens't generate a list but an xrange object which is more efficient in many cases (such as here).

这篇关于有办法避免这种内存错误吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆