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

为何递归函数的默认字典参数在多次调用时未重置?

递归创建频率字典时默认参数异常问题

尝试通过递归实现字符频率统计字典,将空字典设为函数的默认参数,但连续调用该函数定义两个变量时,第二次调用的字典初始值并非空字典,导致结果不符合预期。

问题代码

def freq_dict(list1, a={}):
        if len(list1)>0:
            char1= list1[0]
            if char1 in a.keys():
                a[char1]+=1
                n=a.copy()
                list1=list1[1:]
                return freq_dict(list1, n)
            else:
                a[char1]=1
                n=a.copy()
                list1=list1[1:]
                return freq_dict(list1, n)
        else:
            return a
            
a=freq_dict([1, 2, 2, 1])
b=freq_dict([1, 2, 2, 1])

print(a)
print(b)

预期输出

{1: 2, 2: 2}
{1: 2, 2: 2}

实际问题

第一次调用函数时结果符合预期,但第二次调用时,函数的默认字典初始值变为{1:1},导致最终输出结果异常。


原因分析

Python中可变类型的默认参数只会在函数定义时初始化一次,而非每次调用函数时重新创建。字典是可变对象,第一次调用函数时,直接修改了默认参数对应的字典对象(a[char1]=1),这个修改会被永久保留,导致后续调用时默认参数不再是空字典。

解决方案

不要用可变对象作为默认参数,而是将默认参数设为None,在函数内部判断并初始化空字典:

def freq_dict(list1, a=None):
    # 每次调用时初始化空字典,避免默认参数复用
    if a is None:
        a = {}
    if len(list1) > 0:
        char1 = list1[0]
        if char1 in a:
            a[char1] += 1
        else:
            a[char1] = 1
        # 递归时传递当前字典的副本,避免修改原字典
        return freq_dict(list1[1:], a.copy())
    else:
        return a
            
a=freq_dict([1, 2, 2, 1])
b=freq_dict([1, 2, 2, 1])

print(a)
print(b)

说明

  1. 将默认参数改为None,每次调用函数时都会在内部重新创建空字典,彻底避免了默认参数的复用问题。
  2. 简化了原代码逻辑,去掉重复的列表赋值操作,直接用list1[1:]传递剩余元素。

内容的提问来源于stack exchange,提问作者Arsh Kulshrestha

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 21:40:57