改进了子代码的Python代码数组和平方除数

时间:2017-08-29 19:17:27

标签: python arrays math

来自cw的这个问题要求一个函数接受两个整数并返回一个由两个元素数组组成的数组,每个元素数组由一个整数和它们的平方除数之和组成。该数组必须只包括其整数在两个提供的整数(m,n)范围内的子数组,并且它们对应于完美平方作为其平方除数的总和。

我尝试了下面的代码,它返回了传递样本测试的正确答案,但它运行得太慢而无法通过其余的测试。

我很感激任何提高效率的建议

import math

def is_square(integer):
    root = math.sqrt(integer)
    if int(root + 0.5) ** 2 == integer: 
        return True
    else:
        return False

def list_squared(m, n):
    output_numbers= []
    for N in range(m,n+1):
        div_list = [n for n in range(1,N+1) if N % n == 0]
        sum_sq_div = sum([x**2 for x in div_list])
        if is_square(sum_sq_div)==True:
          output_numbers.append([N,sum_sq_div])
    return output_numbers


In [19]: list_squared(1,2000)
[[1, 1], [42, 2500], [246, 84100], [287, 84100], [728, 722500], [1434, 2856100], [1673, 2856100], [1880, 4884100]]

1 个答案:

答案 0 :(得分:0)

经典的CPU功耗是这一行:

div_list = [n for n in range(1,N+1) if N % n == 0]

好吧,这是列表理解,但是

  • 它总是计算1或NN总是如此
  • 循环直到N如果N很大,这是不必要和浪费的:只是范围直到平方根,并添加补充除数
像这样:

for n in range(2,int((N+1)**0.5)+1):
    if N % n == 0:
        div_list.append(n)
        opposite = N//n
        if n != opposite: # avoid duplicate if square
            div_list.append(opposite)

这会降低从O(N)O(N**0.5)的复杂性。

值为20000,您的代码在28秒内运行,经过上述修改,运行时间为0.4秒,当然结果相同!

除此之外:sum_sq_div = sum([x**2 for x in div_list])可以避免构建listcomp:sum_sq_div = sum(x**2 for x in div_list)稍快一些。

另外:is_square

的更多pythonic代码
def is_square(integer):
    return int(math.sqrt(integer) + 0.5) ** 2 == integer: