Python dictionary setdefault()方法,用作递归函数的返回值

Python dictionary setdefault()方法,用作递归函数的返回值,dictionary,recursion,setdefault,Dictionary,Recursion,Setdefault,假设你想得到第n个斐波那契数。然后,一种可能性是使用递归函数 def Fib(n, d): """Assumes n is an int >= 0, d dictionary Returns nth Fibonacci number""" if n in d: return d[n] else: d[n] = Fib(n-1, d) + Fib(n-2, d)

假设你想得到第n个斐波那契数。然后,一种可能性是使用递归函数

def Fib(n, d):
    """Assumes n is an int >= 0, d dictionary
    Returns nth Fibonacci number"""
    if n in d:
        return d[n]
    else:
        d[n] = Fib(n-1, d) + Fib(n-2, d)
        return d[n]
这很有效。我试着把这个缩短到

 def Fib(n, d):
        return d.setdefault(n, Fib(n-1, d) + Fib(n-2, d))
但是当我可以用你的名字来称呼它的时候

d={0:1, 1:1}
print(f(2, d))
,甚至使用f(1,d),它进入无限循环,并重新启动内核。事实上,这种形式的任何函数

def f(n, d):
    return d.setdefault(n, f(n-1,d))

他也有同样的问题。当我试着调试它时,我看到n一直在减小传递值1。我想我不理解这个方法的实现。我假设setdefault方法首先检查键是否在字典中并返回值,如果不在字典中,则将默认值分配给键并返回默认值。我在这里遗漏了什么?(我正在使用Python3.9.1和Spyder 4.2.0)

您仍然需要一个基本情况,否则没有什么可以阻止它计算,
fib(-1)
fib(-2)
fib(-99)

def fib(n,d):
如果n<2,则返回n。设置默认值(n,fib(n-1,d)+fib(n-2,d))
打印(fib(10,{0:0,1:1}))
55
使用
setdefault
时遇到的问题是python是一种应用程序顺序语言。这意味着在调用函数之前先计算函数参数。在
setdefault
的情况下,在尝试查找
d
中的
n
之前,我们将评估
fib(n-1,d)+fib(n-2,d)

更好的接口可能是
dict.setdefault(key,lambda:somevalue)
,其中仅当需要设置默认值时才执行lambda。我们可以把它写成下面的
lazydefault
-

def lazydefault(d,key,lazyvalue):
如果钥匙不在d中:
d[key]=lazyvalue()
返回d[键]
def纤维(n,d):
返回lazydefault(d,n,lambda:fib(n-1,d)+fib(n-2,d))
打印(fib(10,{0:0,1:1}))
55

您仍然需要一个基本情况,否则没有什么可以阻止它计算,
fib(-1)
fib(-2)
fib(-99)

def fib(n,d):
如果n<2,则返回n。设置默认值(n,fib(n-1,d)+fib(n-2,d))
打印(fib(10,{0:0,1:1}))
55
使用
setdefault
时遇到的问题是python是一种应用程序顺序语言。这意味着在调用函数之前先计算函数参数。在
setdefault
的情况下,在尝试查找
d
中的
n
之前,我们将评估
fib(n-1,d)+fib(n-2,d)

更好的接口可能是
dict.setdefault(key,lambda:somevalue)
,其中仅当需要设置默认值时才执行lambda。我们可以把它写成下面的
lazydefault
-

def lazydefault(d,key,lazyvalue):
如果钥匙不在d中:
d[key]=lazyvalue()
返回d[键]
def纤维(n,d):
返回lazydefault(d,n,lambda:fib(n-1,d)+fib(n-2,d))
打印(fib(10,{0:0,1:1}))
55

谢谢,我明白了!我试图返回
dict.setdefault(d,n,f(n-1,d))
,Python试图首先计算输入,以便能够调用函数。因此,必须坚持你的建议
如果n<2,则返回1,否则d.setdefault(n,fib(n-1,d)+fib(n-2,d))
。谢谢谢谢,我明白了!我试图返回
dict.setdefault(d,n,f(n-1,d))
,Python试图首先计算输入,以便能够调用函数。因此,必须坚持你的建议
如果n<2,则返回1,否则d.setdefault(n,fib(n-1,d)+fib(n-2,d))
。谢谢