Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/332.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/12.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代码优化_Python_Arrays_Algorithm - Fatal编程技术网

计算平方因子列表的python代码优化

计算平方因子列表的python代码优化,python,arrays,algorithm,Python,Arrays,Algorithm,我参加了codewars网站上的python挑战赛。我遇到了以下挑战: 42的除数是:1,2,3,6,7,14,21,42。这些除数的平方是:1,4,9,36,491964411764。除数的平方和是2500,也就是50*50,一个平方 给定两个整数m,n(1对您的代码有几种优化,但最大的优化是当ans*ans大于x时停止: def square_root(x): ans = 0 while True: ans += 1 sqans = ans*a

我参加了codewars网站上的python挑战赛。我遇到了以下挑战:

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


给定两个整数m,n(1对您的代码有几种优化,但最大的优化是当
ans*ans
大于
x
时停止:

def square_root(x):
    ans = 0
    while True:
        ans += 1
        sqans = ans*ans
        if sqans == x:
            return ans
        elif sqans > x:
            return 0
while
中的条件可以删除,因为现在测试是在平方值上进行的

通过这种优化,使用
250500
案例,我从8秒下降到了0.07秒

但这仍然不令人满意。一般来说,包含中断或返回条件的算法至少是
O(n)
,即使可以节省时间,复杂性也太高

只需检查四舍五入的平方根的平方,就可以做得更好:

def square_root(x):
    ans = int(x**0.5 + 0.5)  # rounded just in case it goes below the actual value (float inaccuracy)
    sqans = ans*ans
    return 0 if sqans !=x else x
我将执行时间再除以2(由确认)

除此之外(这并没有加快多少速度,但值得一提):

无需将
map
转换为
sum
中的
list

sq_sum = sum(map(lambda x: x**2,fact(i)))
另外,
fact
可以避免循环到max number。循环到max number除以2并将max number添加到列表中是等效的。max number/2上方不存在更多的除数

def fact(m):
    return [i for i in range(1,m//2+1) if m%i == 0] + [m]
最终编辑:这仍然很慢,因为在
fact
中使用了列表理解。我可以使用生成器来大幅缩短时间,并在其外部添加
m*m

def sqfact(m):
    return (i*i for i in range(1,m//2+1) if m%i == 0)
最后的代码,现在运行得很快,我有0秒的时间

def sqfact(m):
    return (i*i for i in range(1,m//2+1) if m%i == 0)

def square_root(x):
    ans = int(x**0.5 + 0.5)
    return 0 if ans*ans !=x else x

def list_squared(m, n):
    # your code
    fac=[]
    for i in range(m,n+1):
        sq_sum = sum(sqfact(i)) + i*i  # add i square outside
        if square_root(sq_sum):
            fac.append([i,sq_sum])
    return fac

我已经更新了效率非常低的事实函数。现在,我没有迭代到
m
的完整值来找到它的因子,我只去了
sqrt(m)
。这大大减少了运行时间。这背后的逻辑很简单,所以我没有详细说明。下面是为我工作的新代码

def fact(m):

     #determining the lower factors i.e., smaller than sqrt(m)
    fac = [i for i in range(1, int(m**0.5) + 1) if m%i == 0]

     #determining the higher factors i.e., larger than sqrt(m)
    fac = fac + [m//i for i in range(1, int(m**0.5) + 1) if m%i == 0] 

    return sorted(list(set(fac))) #in order to get rid of duplicate factors

两个细节:在
返回ans
之后,您不需要
中断
,因为这将结束函数。
ans=ans+1
也可以缩短为
ans+=1
。另外
sum(list(map(lambda x:x**2,fact(i))
=>sum(map(lambda x:x**2,fact(i)))无需转换为list以比ans=ans+1慢的速度传递到sumis ans+=1?我将后者更改为@numbermiac建议的前者。现在我的示例测试运行时已经慢了很多。我认为不会再慢了。您是否也根据Jean的建议更改了
sum
?如果您更改了,我不知道这是否是r伊森。谢谢你的评论。我可以通过修改平方根函数大约500倍来减少运行时间,尽管方式不同。还有关于事实()的评论函数很有用,但不会显著减少运行时间。即使有了这些改进,代码的效率似乎仍不足以让web提交接受它。请检查我的编辑。检查square更简单。感谢您的评论和努力。我已经投票并接受了此答案,但我仍然无法提交给代码战中的网页提交。它仍然需要一些优化。确实,还有一些其他的大优化。检查我的最终编辑。感谢接受,现在应该可以了。再次感谢。但是这仍然是非常低效的。我现在已经给出了一个答案,它现在非常有效,能够通过挑战。请通过我的回答。我会感谢你的回答。我已经测试过了(没有列表理解)速度差被
square\u root
函数相形见绌,我放弃了它。我想我应该用更大的数字进行测试,因为差异很明显。你仍然需要我对
square\u root
函数进行优化。a,d顺便说一句,我认为不存在重复因子,除非m是平方,所以将1减为1循环结束边界的e,没有
集合
的东西你就可以走了。
def fact(m):
    return [i for i in range(1,m//2+1) if m%i == 0] + [m]
def sqfact(m):
    return (i*i for i in range(1,m//2+1) if m%i == 0)
def sqfact(m):
    return (i*i for i in range(1,m//2+1) if m%i == 0)

def square_root(x):
    ans = int(x**0.5 + 0.5)
    return 0 if ans*ans !=x else x

def list_squared(m, n):
    # your code
    fac=[]
    for i in range(m,n+1):
        sq_sum = sum(sqfact(i)) + i*i  # add i square outside
        if square_root(sq_sum):
            fac.append([i,sq_sum])
    return fac
def fact(m):

     #determining the lower factors i.e., smaller than sqrt(m)
    fac = [i for i in range(1, int(m**0.5) + 1) if m%i == 0]

     #determining the higher factors i.e., larger than sqrt(m)
    fac = fac + [m//i for i in range(1, int(m**0.5) + 1) if m%i == 0] 

    return sorted(list(set(fac))) #in order to get rid of duplicate factors