我的代码给出了超出限制的Key错误

时间:2016-03-17 14:41:07

标签: python python-3.x factorial keyerror

我正在解决Project Euler 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

我也打印了清单,发现那里没有问题。

我哪里错了?

2 个答案:

答案 0 :(得分:4)

您未正确使用functools.reduce()

这个:[{1}}应用于[1,4,0​​]将(尝试)计算:

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

导致此索引错误(factDict [1] + factDict [4]等于25)。

根据to the doc

  

左参数x是累计值

因此,如果你使用factDict [x],你将用它的阶乘代替累积值(不是你想要的)。

所以你必须单独留下x&#39;。

然后,要初始化为&#34;中性&#34;,你可以只使用0,这样,它实际上会计算(对于140):factDict[factDict[1] + factDict[4]] + factDict[0]

最后:

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)) 中的最后一次测试,因为你正在寻找等于其阶乘之和的数字,而不是它们的阶乘之和的除数。 (如评论中所述,您可以使用您喜欢的测试。)

PS这并没有给出很多结果:

sumFact == i

答案 1 :(得分:1)

reduce方法不能按预期工作。访问https://docs.python.org/2/library/functions.html#reduce

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

表达式x是累加值,y是迭代(listNum)的更新值。 发生异常时,listNum的值为[1,4,0​​]。那时由reduce函数进行的计算是:

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.

解决此问题的方法是将初始化程序设置为reduce函数,如下所示。

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) 

请注意,此代码将显示数字,这些数字除以其数字的阶乘之和。