Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 3.x 优化CodeWars Python 3.6代码:整数:1_Python 3.x_Optimization - Fatal编程技术网

Python 3.x 优化CodeWars Python 3.6代码:整数:1

Python 3.x 优化CodeWars Python 3.6代码:整数:1,python-3.x,optimization,Python 3.x,Optimization,我需要帮助优化我的Python3.6代码以获得CodeWars整数:1 Kata 给我们一系列的数字,我们必须返回数字和除数的平方和,即平方本身 42的除数是:1,2,3,6,7,14,21,42。这些除数的平方是:1,4,9,36,49,196,441,1764。平方除数之和是2500,也就是50*50,一个平方 给定两个整数m,n(1这更多的是数学问题。i的两个最大除数是i本身和i/2。因此,只需使用i//2+1作为范围停止,而不是i+1,您就可以将代码加速两次。只是不要忘记增加i**2的s

我需要帮助优化我的Python3.6代码以获得CodeWars整数:1 Kata

给我们一系列的数字,我们必须返回数字和除数的平方和,即平方本身

42的除数是:1,2,3,6,7,14,21,42。这些除数的平方是:1,4,9,36,49,196,441,1764。平方除数之和是2500,也就是50*50,一个平方


给定两个整数m,n(1这更多的是数学问题。i的两个最大除数是i本身和i/2。因此,只需使用
i//2+1
作为范围停止,而不是
i+1
,您就可以将代码加速两次。只是不要忘记增加
i**2
sq divs
。 您可能希望获得一些微小的性能改进,不包括
sq
变量和
sq_divs**(1/2)

顺便说一句,您应该在第一个范围内使用n+1停止

def list_squared(m, n):
    sqsq = []
    for i in range(m, n+1):
        divisors = [j * j for j in range(1, i // 2 + 1 #speed up twice
            ) if i % j == 0]
        sq_divs = sum(divisors)
        sq_divs += i * i #add i as divisor
        if ((sq_divs) ** 0.5) % 1 == 0: #tiny speed up here
            sqsq.append([i, sq_divs])
    return sqsq

UPD:我试过Kata,但它仍然超时。所以我们需要更多的数学!如果I可以被j除,那么它也可以被I/j除,所以我们可以使用sqrt(I)
int(math.sqrt(I))+1)
)当范围停止时。
如果i%j==0
则将
j*j
附加到除数数组中。如果i/j!=j则将
(i/j)**2

通过将最大范围设置为
sqrt(num),可以将列表理解中循环的复杂性从
O(N)
降低到
O(Log((N))
+1
而不是
num

通过从1循环到sqrt(num)+1,我们可以得出结论,如果i(循环中的当前项)是num的一个因子,那么num除以i一定是另一个因子

例:2是10的系数,5也是10(10/2)

以下代码通过了所有测试:

import math

def list_squared(m, n):
    result = []
    for num in range(m, n + 1):
        divisors = set()
        for i in range(1, int(math.sqrt(num)+1)):
            if num % i == 0:
                divisors.add(i**2)
                divisors.add(int(num/i)**2)
        total = sum(divisors)
        sr = math.sqrt(total)
        if sr - math.floor(sr) == 0:
            result.append([num, total])
    return result

我看到使用
j*j
而不是
j**2
可以稍微提高速度。例如:
python3-m timeit'对于范围内的I(11000):[j*j对于范围内的j(1,I+1),如果I%j==0],
,但是你自己试试。另外一个小小的改进是使用
sq=sq_divs**0.5
import math

def list_squared(m, n):
    result = []
    for num in range(m, n + 1):
        divisors = set()
        for i in range(1, int(math.sqrt(num)+1)):
            if num % i == 0:
                divisors.add(i**2)
                divisors.add(int(num/i)**2)
        total = sum(divisors)
        sr = math.sqrt(total)
        if sr - math.floor(sr) == 0:
            result.append([num, total])
    return result