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()是好的。你知道吗
你的问题是:
这将构造一个列表,然后从该列表中构造一个集合,然后取集合的长度。你不需要做任何工作(
range()
,或者xrange()
对于这个问题,不产生重复的对象,所以我们不需要集合,sum()
工作在任何iterable对象上,所以你也不需要列表)。当我们讨论这个问题时,divmod(n, x)[1]
只是一种非常精细的编写n % x
的方法,它会消耗一点额外的内存来构造一个元组(由于您将元组扔掉,因此会立即回收元组)。以下是固定版本:您不需要测试每一个可能的除数,测试到sqrt(n)就足够了。这将使函数O(sqrt(n))代替O(n)。你知道吗
在我使用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()
是好的。你知道吗相关问题 更多 >
编程相关推荐