1

我写了一个 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变成了否定的。我不明白这一点。我在网上查到了这个。但是,不幸的是找不到任何答案。请有人可以向我解释这里发生了什么?

4

2 回答 2

3

在 Python 中,函数调用使用“渴望”评估——在调用函数之前计算值,而不是在函数实际使用它们时计算它们。

因此,在

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

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

于 2020-04-07T07:14:37.140 回答
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

一样简洁,只有在实际输入逻辑分支时才会评估相应的表达式。

于 2020-04-07T07:14:50.867 回答