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

Python字典按键前缀分组及代码优化问题咨询

解决方案与问题解答:字典分组、setdefault用法及列表赋值陷阱

嘿,作为Python新手遇到这些问题太正常了,我来一步步帮你拆解解决:

一、最优字典分组方案(用collections.defaultdict)

这应该是最符合你需求的高效方案,defaultdict就是专门用来处理这种需要自动初始化容器的场景的,代码写起来也清爽:

from collections import defaultdict

a = {'a1':'obj_1','b1':'obj_2','c1':'obj_3','a2':'obj_4','b2':'obj_5','c2':'obj_6'}
result = defaultdict(dict)  # 告诉它,每个新键对应的值是个空字典

for key, value in a.items():
    # 取键的第一个字符,拼接成你要的分组名(比如'a'→'aonly')
    group_key = f"{key[0]}only"
    # 直接往对应的分组字典里加键值对就行,defaultdict会自动创建空字典
    result[group_key][key] = value

# 如果最后需要把defaultdict转成普通字典(可选,不转也能用)
result = dict(result)
print(result)

运行后就能得到你想要的结果:

{'aonly': {'a1': 'obj_1', 'a2': 'obj_4'}, 'bonly': {'b1': 'obj_2', 'b2': 'obj_5'}, 'conly': {'c1': 'obj_3', 'c2': 'obj_6'}}

这个方法的时间复杂度是O(n),只需要遍历一次原字典,效率拉满。

二、你的setdefault方法为什么没成功?

大概率是你之前的写法有问题,setdefault其实完全可以实现这个需求,正确的用法应该是这样:

a = {'a1':'obj_1','b1':'obj_2','c1':'obj_3','a2':'obj_4','b2':'obj_5','c2':'obj_6'}
result = {}

for key, value in a.items():
    group_key = f"{key[0]}only"
    # 核心:setdefault会返回对应键的值,如果键不存在就先设置成空字典再返回
    result.setdefault(group_key, {})[key] = value

print(result)

你可能之前错误地把setdefault的返回值浪费了,比如单独写result.setdefault(group_key, {})然后再去赋值result[group_key][key] = value,其实链式调用一步就搞定了,这样写和defaultdict效率差不多,只是代码稍微啰嗦一点。

三、l = m = n = []为什么会出问题?

这是Python里非常经典的可变对象赋值陷阱!列表是可变对象,当你用这种单行赋值时,l、m、n三个变量其实都指向同一个内存地址里的空列表,它们并不是三个独立的列表。

比如你试试这段代码:

l = m = n = []
l.append(1)
print(m)  # 输出[1]
print(n)  # 输出[1]

是不是很意外?因为它们本质上是同一个东西。正确创建三个独立空列表的写法应该是:

l = []
m = []
n = []

或者用更简洁的列表推导式:

l, m, n = [[] for _ in range(3)]

这样每个变量都是独立的列表对象,就不会互相影响了。

四、为什么列表转字典的方法效率低?

你之前用列表存储再转字典的思路,大概是先把每个分组的键值对存成列表,最后再转成字典,比如:

# 大概是类似这样的低效写法
a_groups = {'aonly': [], 'bonly': [], 'conly': []}
for key, value in a.items():
    if key.startswith('a'):
        a_groups['aonly'].append((key, value))
    elif key.startswith('b'):
        a_groups['bonly'].append((key, value))
    elif key.startswith('c'):
        a_groups['conly'].append((key, value))
result = {k: dict(v) for k, v in a_groups.items()}

这种方法多了一步“列表转字典”的操作,而且如果分组变多,判断条件也会越来越长。而用defaultdict或setdefault的方法,是在遍历原字典的过程中直接构建目标字典,一步到位,内存占用更少,速度也更快。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 13:27:50