You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 14:15:41