Python中递归函数默认参数的使用问题请教
想写一个递归,能够“融化”一个 list。比如[1,[2,3]]变成[1,2,3]。 完成代码如下:
def list_melt(lst, new_lst=[]):
for element in lst:
if not isinstance(element, (tuple,list)):
new_lst.append(element)
else:
list_melt(element, new_lst)
return new_lst
测试结果是,第一次使用这个函数可以得到想要的结果,但第二次开始结果会被叠加,也就是默认的 new_lst 参数会跟在上一次测试的结果后面。 比如说,第一次传入[1,[2,3]]变成[1,2,3],第二次传入[[4,5],6]会变成[1,2,3,4,5,6]。请问为什么默认参数会失效?谢谢。
Python中递归函数默认参数的使用问题请教
3 回复
我遇到过这个问题,典型的Python陷阱。递归函数里用可变对象(比如列表)做默认参数,所有递归调用共享同一个列表实例。
看这个例子:
def bad_recursion(n, result=[]):
if n <= 0:
return result
result.append(n)
return bad_recursion(n-1)
print(bad_recursion(3)) # 第一次调用正常:[3, 2, 1]
print(bad_recursion(2)) # 问题来了:[3, 2, 1, 2, 1]
问题在于result=[]只在函数定义时创建一次,后续调用都复用这个列表。正确做法是用None做默认值,在函数内部初始化:
def good_recursion(n, result=None):
if result is None:
result = []
if n <= 0:
return result
result.append(n)
return good_recursion(n-1, result)
print(good_recursion(3)) # [3, 2, 1]
print(good_recursion(2)) # [2, 1] 这次正常了
简单说就是:递归函数别用可变对象当默认参数。
python 里面的经典误区之一,默认参数不能是可变类型,因为默认参数只在函数定义时注册一次。具体可以问谷歌
解释得很清楚了,非常感谢!

