如何优化python代码:Euler project prop 4

时间:2012-09-03 21:33:25

标签: python

我一直在研究Euler project problem 4,我的代码运行正常,但需要花费太多时间(0.41秒)。我如何优化它以便花费更少的时间。我有一个技巧我是遗失,或者我不知道的特殊功能?
这是代码:

#Note: tpal is a function to test if number is palindrome

pal =0

for i in range(999,100,-1):
    if pal >= i*999:    #A way to get out of loop and to not test on all numbers
        break 
    for j in range(999,100,-1):
        if pal >= i*999:
            break 
        if j > i:                         #numbers would already have been tested so I skip them 
            continue
        pot=i*j
        if ((tpal(pot)==1)and(pot> pal)):
            pal=pot
            i1=i
            j1=j

print(i1,j1,pal)

def tpal(num):
    num=list(str(num))
    Le=len(num)
    if Le == 1: # if number is of one digit than palindrome
        return 1

    le=len(num)

    if le%2 !=0: #4 example 10101even nbr
        le-=1
    le/2    

    for i in range(0,le):
       if num[i]!=num[Le-i-1]:
           return 0

    return 1                  

3 个答案:

答案 0 :(得分:2)

现在事实证明代码已经< 1 s运行时,它不再那么有趣了。您可以修改代码以测试更少的数字并尽快放弃。但有一个明显的优化,有点可爱。这一行:

        if ((tpal(pot)==1)and(pot> pal)):

每次检查是否有什么是回文,即使是pot <= pal。回文试验很昂贵。如果你只是交换订单:(注意你不需要==1):

        if (pot > pal) and tpal(pot):
那么你可以节省很多时间:

In [24]: timeit orig()
1 loops, best of 3: 201 ms per loop

In [25]: timeit orig_swapped()
10 loops, best of 3: 30.1 ms per loop

因为如果A and B已经为假,A不评估B,因此它知道A and B必须为false。 (这称为“短路”;如果A为真,则“A或B”也会发生同样的情况。)

顺便提一下,最后一行在这里:

if le%2 !=0: #4 example 10101even nbr
    le-=1
le/2    
^^^^

不会更改le。我认为这三行意味着le //= 2

答案 1 :(得分:1)

试试这个,它不应该花费长达31秒的时间:

def isPalindrome(n):
    return str(n) == str(n)[::-1]

def listNums():
    a, b, pal = 0, 0, 0;
    for i in range(999, 99, -1):
        for j in range(999, 99, -1):
            n = i * j
            if isPalindrome(n) and n > pal:  # better to use "n > pal and isPalindrome(n)" instead, see other answer for details.
                a, b, pal = i, j, n
    return a, b, pal             

print listNums()

运行此操作大约需要1秒钟。对于这样的事情你肯定不需要循环中那些多余的if语句 - 如果你循环,比如说,range(9999, 999, -1),你可能会考虑进行一些这样的优化(当然,有一个可以对这样的事情进行多种潜在的优化,例如,不能遍历每个i,j对两次)。

答案 2 :(得分:0)

没有给你完整的答案。这是一些指针。

  • 重新考虑你的for循环,它们是复杂的。也许内循环应该从i开始?
  • 删除所有那些愚蠢的句子,如果你的循环是正确的,你就不需要它们。
  • 最后,int(str(pot)[::-1])==pot然后是它的回文

编辑: 让男/女解决他/她自己的问题。无需在此处发布解决方案。