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



我编写了一个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中,函数调用使用"渴望"求值——在调用函数之前计算值,而不是在函数实际使用值时计算值。

因此,在中

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

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

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

同样简洁,并且只有在实际输入了各自的逻辑分支时才会对其进行求值。

最新更新