我正在解决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
我也打印了清单,发现那里没有问题。
我哪里错了?
答案 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)
请注意,此代码将显示数字,这些数字除以其数字的阶乘之和。