【问题标题】:My code gives Key error beyond a limit我的代码给出了超出限制的密钥错误
【发布时间】:2016-03-17 14:41:06
【问题描述】:

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

我也打印了列表,发现没有问题。

我哪里错了?

【问题讨论】:

    标签: python python-3.x factorial keyerror


    【解决方案1】:

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

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

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

    【讨论】:

    • 感谢您的回复!听了你的解释我才明白。但是问题是除数,因为 19 满足,所以您的最后一次编辑不是必需的。无论如何,感谢您的澄清。还有使用reduce的更好方法吗?
    • 哼,在问题或问题 34 中看不到任何除数,但无论如何,最后一个测试可以设置为适合您的需要。是的,我找到了更好的方法,我编辑了答案。
    • 完成。如果有帮助,请不要犹豫,接受我的回答。
    【解决方案2】:

    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) 
    

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

    【讨论】:

      猜你喜欢
      • 2018-08-23
      • 2016-10-02
      • 1970-01-01
      • 1970-01-01
      • 2020-12-13
      • 2022-01-06
      • 2020-10-14
      • 2017-12-19
      • 1970-01-01
      相关资源
      最近更新 更多