[使用dict.get()方法进行阶乘的python代码中的无限递归

问题描述 投票:1回答:2

我写了一个Python函数来计算数字的阶乘;

def fact(n):
    return {0: 1}.get(n, n * fact(n-1))

我很惊讶地发现,即使对于fact(0),它也会导致无限递归。然后我添加了一个断言,就像这样;

def fact(n):
    assert n >= 0
    return {0: 1}.get(n, n * fact(n-1))

但是这次AssertionError出现了,意味着n变为负数。我不明白我在互联网上查询了此内容。但是,不幸的是找不到任何答案。请有人能告诉我这里发生了什么吗?

python dictionary factorial infinite-recursion
2个回答
3
投票

在Python中,函数调用使用'eager'评估-值是在调用函数之前计算的,而不是在函数实际使用它们时对其进行计算。

因此,在

    {0: 1}.get(n, n * fact(n-1))

表达式n * fact(n-1)的求值之前甚至调用get()。即即使get()根本不需要该值,该表达式也会被求值。这就是触发递归的原因。


2
投票

dict.get(item, default=None)只是一个带有1个或两个可选参数的函数。如果您将n * fact(n-1)作为默认值传递,则该表达式在传递前将被求值。整体

return {0: 1}.get(n, n * fact(n-1))

构造似乎有点人为。比较简单

return n * fact(n-1) if n else 1

同样简洁,仅当实际输入了它们的逻辑分支时,才对相应的表达式求值。

© www.soinside.com 2019 - 2024. All rights reserved.