我写了一个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中,函数调用使用'eager'评估-值是在调用函数之前计算的,而不是在函数实际使用它们时对其进行计算。
因此,在
{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
同样简洁,仅当实际输入了它们的逻辑分支时,才对相应的表达式求值。