如何优化Python代码以使用更少的内存执行计算?

2024-04-18 15:31:54 发布

您现在位置:Python中文网/ 问答频道 /正文

为了确定一个数的除数是奇数还是偶数,我把下面的代码放在一起。该代码在相对较小的数字下运行良好,但一旦输入较大的数字(如9位数字),它就会挂断。你知道吗

def divisors(n):
    num = len(set([x for x in range(1,n+1) if not divmod(n,x)[1]]))
    if (num != 0 and num % 2 == 0):
        return 'even'
    else:
        return 'odd'

我能做些什么来提高效率?你知道吗


Tags: 代码inforlenreturnifdefrange
2条回答

你的问题是:

num = len(set([x for x in range(1,n+1) if not divmod(n,x)[1]]))

这将构造一个列表,然后从该列表中构造一个集合,然后取集合的长度。你不需要做任何工作(range(),或者xrange()对于这个问题,不产生重复的对象,所以我们不需要集合,sum()工作在任何iterable对象上,所以你也不需要列表)。当我们讨论这个问题时,divmod(n, x)[1]只是一种非常精细的编写n % x的方法,它会消耗一点额外的内存来构造一个元组(由于您将元组扔掉,因此会立即回收元组)。以下是固定版本:

num = sum(1 for x in xrange(1,n+1) if not n % x)

您不需要测试每一个可能的除数,测试到sqrt(n)就足够了。这将使函数O(sqrt(n))代替O(n)。你知道吗

import math

def num_divisors(n):
    sqrt = math.sqrt(n)
    upper = int(sqrt)
    num = sum(1 for x in range(1, upper + 1) if not n % x)
    num *= 2
    if upper == sqrt and num != 0:
        num -= 1
    return num

在我使用python2的基准测试中,这比使用sum(1 for x in range(1, n + 1) if not n % x)n = int(1e6)快1000倍,对于1e8快10000倍。对于1e9,后一段代码给了我一个内存错误,表明在进行求和之前整个序列都存储在内存中,因为在python 2中range()返回一个列表,我应该使用xrange()。对于Python来说range()是好的。你知道吗

相关问题 更多 >