Python递归函数默认字典参数异常原因咨询
Python 默认字典参数异常的原因解析
示例代码
def canSum(targetSum, numbers, m = {}): if targetSum in m: return m[targetSum] if targetSum == 0: return True if targetSum < 0: return False for number in numbers: remainder = targetSum - number if canSum(remainder, numbers, m): m[targetSum] = True return True m[targetSum] = False return False print(f'Answer: {canSum(7, [2, 3])}') # true print(f'Answer: {canSum(7, [5, 3, 4, 7])}') # true print(f'Answer: {canSum(7, [2, 4])}') # false print(f'Answer: {canSum(8, [2, 3, 5])}') # true print(f'Answer: {canSum(300, [7, 14])}') # false
问题描述
当移除函数参数的默认值,调用时手动传入空字典,代码运行正常;但使用默认空字典参数、不手动传入时会出现异常。同样写法在JavaScript中可正常运行,请教Python中该现象的原因。
原因分析
Python 与 JavaScript 在默认参数的处理逻辑上有本质区别:
- Python 的默认参数是在函数定义时初始化:函数定义阶段,默认参数
m={}就会被创建为一个实际的字典对象。之后每次调用函数如果不手动传入m,都会复用这个已经存在的字典,而不是创建新的空字典。你的递归逻辑会不断往这个共享字典中写入缓存数据,后续调用会读取到之前的残留数据,导致逻辑判断出错。 - JavaScript 的默认参数是在函数调用时求值:每次调用函数时,如果没有传入对应参数,才会重新创建一个新的空对象
{},不会出现跨调用的状态共享,因此逻辑可以正常运行。
解决方法
把默认参数改为None,在函数内部初始化空字典,确保每次调用都会创建新的缓存容器:
def canSum(targetSum, numbers, m = None): # 每次调用不传m时,创建新的空字典 if m is None: m = {} if targetSum in m: return m[targetSum] if targetSum == 0: return True if targetSum < 0: return False for number in numbers: remainder = targetSum - number if canSum(remainder, numbers, m): m[targetSum] = True return True m[targetSum] = False return False
内容的提问来源于stack exchange,提问作者karassay.raushanbek
相关产品推荐
相关产品推荐

