2016-03-17 58 views
1

我解決項目歐拉problem 34我的代碼給出超出極限的關鍵錯誤

我的代碼給出如下:

import functools 

limit = int(input()) 

factDict = { 0:1, 1:1, 2:2, 3:6, 4:24, 5:120, 6:720, 7:5040, 8:40320, 9:362880 } 

for i in range(10, limit): 
    listNum = list(map(int, list(str(i)))) 
    #print(listNum) 
    sumFact = functools.reduce(lambda x, y: factDict[x] + factDict[y], listNum) 
    if(sumFact%i == 0): 
     print(i) 

它正常工作,直到140,然後給出了:

Traceback (most recent call last): 
    File "solution.py", line 10, in <module> 
    sumFact=functools.reduce(lambda x, y: factDict[x]+factDict[y], listNum) 
    File "solution.py", line 10, in <lambda> 
    sumFact=functools.reduce(lambda x, y: factDict[x]+factDict[y], listNum) 
KeyError: 25 

我也打印了清單,發現那裏沒有問題。

我哪裏錯了?

回答

3

您沒有正確使用functools.reduce()

此:functools.reduce(lambda x, y: factDict[x] + factDict[y], listNum)施加到[1,4,0]將(嘗試)計算:

factDict[factDict[1] + factDict[4]] + factDict[0] 

造成這種索引錯誤(factDict [1] + factDict [4]等於25) 。

根據to the doc

左參數x是累計值

所以如果你使用factDict [X]你會被它的階乘(不更換累計值你想)。

所以你必須離開x'單獨'。

然後,初始化的東西 「中性」,你可以用0,這樣一來,它實際上將計算(140):0 + factDict[1] + factDict[4] + factDict[0]

所以最後:

#!/usr/bin/env python3 

import functools 

limit = int(input()) 

factDict = { 0:1, 1:1, 2:2, 3:6, 4:24, 5:120, 6:720, 7:5040, 8:40320, 9:362880 } 

for i in range(10, limit): 
    listNum = list(map(int, list(str(i)))) 
    #print(listNum) 
    sumFact = functools.reduce(lambda x, y: x + factDict[y], listNum, 0) 
    if(sumFact == i): 
     print("Found: " + str(i)) 

而且我改變sumFact == i中的最後一項測試,因爲您正在查找的數字等於它們的因子總和,而不是它們因子的總和的除數。 (正如評論所述,你可以使用你喜歡的測試)。

PS這不給了不少成果:當你打算

$ ./test_script.py 
1000000 
Found: 145 
Found: 40585 
+0

感謝您的回覆!我在你的解釋後意識到。但是這個問題指出了除數,因爲你不需要19的最後編輯就滿足了。無論如何感謝澄清。還有更好的方法使用減少? –

+0

哼哼,在問題或問題34中看不到任何除數,但這最後一個測試可以設置爲適合您的需求。是的,我找到了更好的方法,我編輯答案。 – zezollo

+0

完成。如果有幫助,請不要猶豫,接受我的回答。 – zezollo

1

的降低方法不起作用。在該表達式x訪問https://docs.python.org/2/library/functions.html#reduce

sumFact = functools.reduce(lambda x, y: factDict[x] + factDict[y], listNum). 

是累積值和y爲可迭代(LISTNUM)更新值。 發生異常時,listNum的值爲[1,4,0​​]。通過在那一刻精簡函數進行的計算則是:

accum_value = factDict[1]+factDict[4] # accum_value is set to 25 
accum_value = factDict[accum_value]+factDict[0] # Keyerror factDict does not have the key 25. 

以糾正這種情況的方法是設置一個初始化到這樣的降低作用。

import functools 
limit = int(input()) 
factDict = { 0:1, 1:1, 2:2, 3:6, 4:24, 5:120, 6:720, 7:5040, 8:40320, 9:362880 } 

for i in range(10, limit): 
    listNum = list(map(int, list(str(i)))) 
    #print(listNum) 
    sumFact = functools.reduce(lambda x, y: x + factDict[y], listNum[1:len(listNum)],factDict[listNum[0]]) 
    #print sumFact 
    if(sumFact%i == 0): 
     print(i) 

請注意,此代碼將顯示按照他們的數字階乘的總和進行區分的數字。