Python递归调用时默认参数memo未重置的原因解析
Python默认参数的绑定机制——为什么你的斐波那契递归代码不用显式传memo也能工作?
这事儿的核心在于Python处理默认参数的特殊逻辑:函数的默认参数是在函数定义的时候就初始化完成的,不是每次调用函数时重新创建。
具体到你的代码:
- 当你写下
def fib(n, memo=[1,1]):这行代码时,Python就已经创建了一个[1,1]的列表对象,并且把这个对象和memo参数绑定在了一起。 - 之后不管你调用多少次
fib,只要不主动传入memo参数,就会一直复用这个一开始就创建好的列表,而不是每次都生成新的[1,1]。
再看你的递归过程:
- 第一次调用
fib(100)时,用的是初始的memo=[1,1]。 - 进入
else分支后,递归调用fib(n-1)和fib(n-2),这两个调用都没传memo,所以用的还是同一个列表。 - 每次执行
memo.append(fib(n-1)+fib(n-2)),都是在修改这个唯一的列表,所以递归过程中算出的结果会被持续存在里面,自然不用显式把memo传进去也能保存状态。
你之前误以为要写成fib(n-1, memo)才行,但其实显式传参只是把同一个列表对象再传一遍,和用默认参数的效果完全一样——本质上都是操作同一个列表。
不过要注意:这种特性如果用不好容易踩坑。比如你如果多次调用fib(5),第二次调用时memo已经是第一次调用后被拉长的列表了,会直接返回结果,而不是重新计算。这是因为可变默认参数会保留之前调用的状态。
内容的提问来源于stack exchange,提问作者Boopesh
相关产品推荐
相关产品推荐

