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

python代码中使用dict.get()方法实现阶乘的无限递归,python,dictionary,factorial,infinite-recursion,Python,Dictionary,Factorial,Infinite Recursion,我编写了一个Python函数来计算一个数字的阶乘,如下所示 def fact(n): return {0: 1}.get(n, n * fact(n-1)) def fact(n): assert n >= 0 return {0: 1}.get(n, n * fact(n-1)) 我惊讶地看到,它导致无限递归,即使对于fact(0)。然后我添加了一个断言,就像这样 def fact(n): return {0: 1}.get(n, n * fact(n

我编写了一个Python函数来计算一个数字的阶乘,如下所示

def fact(n):
    return {0: 1}.get(n, n * fact(n-1))
def fact(n):
    assert n >= 0
    return {0: 1}.get(n, n * fact(n-1))
我惊讶地看到,它导致无限递归,即使对于
fact(0)
。然后我添加了一个断言,就像这样

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

但是这次AssertionError被提出,意思是
n
变为负值。我不明白。我在网上查到的。但不幸的是,我找不到任何答案。有人能给我解释一下这里发生了什么吗?

在Python中,函数调用使用“渴望”求值——值是在调用函数之前计算出来的,而不是在函数实际使用它们时计算出来的

因此,在

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

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

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

因此,在

{0:1}.get(n,n*事实(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
同样简洁,仅当实际输入其逻辑分支时才会计算相应的表达式。

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

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

n*fact(n-1)
需要计算n是否在字典中,因为这是一个要获取的参数。我不确定您的意思。您能详细说明一下吗?所有要获取的参数(或任何其他函数或方法)在调用之前都需要求值。把它想象成
default=n*fact(n-1);返回{0:1}.get(n,默认值)
。现在是不是很明显,这条线永远都达不到?我现在明白了。因此调用
fact(0)
的计算结果为
{0:1}.get(0,fact(-1))
,这使得断言失败。。。谢谢@jornsharpe
n*事实(n-1)
需要评估n是否在字典中,因为这是一个要获取的参数。我不确定你的意思。您能详细说明一下吗?所有要获取的参数(或任何其他函数或方法)在调用之前都需要求值。把它想象成
default=n*fact(n-1);返回{0:1}.get(n,默认值)
。现在是不是很明显,这条线永远都达不到?我现在明白了。因此调用
fact(0)
的计算结果为
{0:1}.get(0,fact(-1))
,这使得断言失败。。。谢谢你@jornsharpeaha!所以,表达式(n*fact(n-1)的值必须在第一次调用函数时预先知道?我现在知道了。谢谢你给出了非常清楚的答案。啊哈!那么,表达式(n*fact(n-1)的值必须在第一次调用函数时提前知道?我现在明白了。谢谢你给出了非常清晰的答案。你是对的。但我只是想用字典来进行分支而不是控制结构。实际上,这是我的初衷。谢谢。你是对的。但我只是想用字典来进行分支而不是控制结构结构。事实上,这是我的初衷。谢谢。