2014-12-18 42 views
0

我有一個腳本可以找到所有數字的總和,這些數字可以寫成他們數字的五次冪的總和。 (這個問題更詳細的描述on the Project Euler web site。)列表解析和循環之間的性能差異

我寫了兩種方式,但我不明白性能的差異。

第一種方式使用嵌套列表解析:

exp = 5 

def min_combo(n): 
    return ''.join(sorted(list(str(n)))) 

def fifth_power(n, exp): 
    return sum([int(x) ** exp for x in list(n)]) 

print sum([fifth_power(j,exp) for j in set([min_combo(i) for i in range(101,1000000) ]) if int(j) > 10 and j == min_combo(fifth_power(j,exp)) ]) 

和型材這樣的:

$ python -m cProfile euler30.py 
443839 
     3039223 function calls in 2.040 seconds 

    Ordered by: standard name 

    ncalls tottime percall cumtime percall filename:lineno(function) 
    1007801 1.086 0.000 1.721 0.000 euler30.py:10(min_combo) 
    7908 0.024 0.000 0.026 0.000 euler30.py:14(fifth_power) 
     1 0.279 0.279 2.040 2.040 euler30.py:6(<module>) 
     1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects} 
    1007801 0.175 0.000 0.175 0.000 {method 'join' of 'str' objects} 
     1 0.013 0.013 0.013 0.013 {range} 
    1007801 0.461 0.000 0.461 0.000 {sorted} 
    7909 0.002 0.000 0.002 0.000 {sum} 

第二種方法是更常用的for循環:

exp = 5 
ans= 0 

def min_combo(n): 
    return ''.join(sorted(list(str(n)))) 


def fifth_power(n, exp): 
    return sum([int(x) ** exp for x in list(n)]) 


for j in set([ ''.join(sorted(list(str(i)))) for i in range(100, 1000000) ]): 
    if int(j) > 10: 

     if j == min_combo(fifth_power(j,exp)): 
      ans += fifth_power(j,exp) 

print 'answer', ans 

這裏是再次分析信息:

$ python -m cProfile euler30.py 
answer 443839 
     2039325 function calls in 1.709 seconds 

    Ordered by: standard name 

    ncalls tottime percall cumtime percall filename:lineno(function) 
    7908 0.024 0.000 0.026 0.000 euler30.py:13(fifth_power) 
     1 1.081 1.081 1.709 1.709 euler30.py:6(<module>) 
    7902 0.009 0.000 0.015 0.000 euler30.py:9(min_combo) 
     1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects} 
    1007802 0.147 0.000 0.147 0.000 {method 'join' of 'str' objects} 
     1 0.013 0.013 0.013 0.013 {range} 
    1007802 0.433 0.000 0.433 0.000 {sorted} 
    7908 0.002 0.000 0.002 0.000 {sum} 

爲什麼列表理解實現調用min_combo()比for循環實現多1,000,000次?

回答

2

因爲在第二個你再實施的min_comboset調用裏面的內容...

做同樣的事情,你就會有同樣的結果。

BTW,改變那些避免被創建的大名單:

sum([something for foo in bar]) - >sum(something for foo in bar)

set([something for foo in bar]) - >set(something for foo in bar)

(不[...]他們成爲發電機表達式)。

相關問題