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

Python 3.4中如何保留字典重复键以完整生成嵌套字典并排序

解决Python字典重复键丢失条目问题

问题背景

我希望最后一个用于排序的for循环能展示字典names的所有条目,包括重复键(一对多映射)的条目。但在生成嵌套字典列表users时,有2个Tom和1个Bernie条目丢失,如何在Python 3.4中避免该问题?

原始代码

from operator import itemgetter
names = {
    'Bucky': 'Roberts',
    'Tom': 'Roberts',
    'Bernie' : 'Zunks',
    'Jenna' : 'Hayes',
    'Sally': 'Jones',
    'Amanda':'Roberts',
    'Tom':'Williams',
    'Dean':'Hayes',
    'Bernie':'Barbie',
    'Tom':'Jones'
}
users = []
for k,v in names.items():
    users.append({'fname':k,'lname':v})
print(users)
for x in sorted(users, key=itemgetter('fname')):
    print(x)

问题原因

其实你踩了Python字典的一个基础特性:字典的键是绝对唯一的。当你在names里重复给同一个键赋值时,后面的值会直接覆盖掉前面的。比如Tom先后被赋值三次,最终字典里只会留下最后一次的Tom: Jones;Bernie两次赋值后也只剩Bernie: Barbie。所以遍历字典items()的时候,自然拿不到那些被覆盖的旧条目。

两种可行解决方案

方案1:用列表+元组存储原始数据

既然字典存不了重复键的条目,那我们直接用元组列表来保存所有原始键值对,这样就能完整保留每一条数据:

from operator import itemgetter
# 把原来的字典改成元组列表,保留所有条目
names = [
    ('Bucky', 'Roberts'),
    ('Tom', 'Roberts'),
    ('Bernie', 'Zunks'),
    ('Jenna', 'Hayes'),
    ('Sally', 'Jones'),
    ('Amanda', 'Roberts'),
    ('Tom', 'Williams'),
    ('Dean', 'Hayes'),
    ('Bernie', 'Barbie'),
    ('Tom', 'Jones')
]
users = []
for k, v in names:
    users.append({'fname': k, 'lname': v})
print(users)
# 排序后输出所有条目
for x in sorted(users, key=itemgetter('fname')):
    print(x)

运行这段代码,你就能看到所有3个Tom和2个Bernie的条目都被保留并排序输出了。

方案2:用defaultdict实现多值映射

如果后续还需要按键来管理多个值,可以用collections模块里的defaultdict来构建一个多值字典,把同一个键对应的所有值都存到列表里,之后再展开成你需要的users列表:

from operator import itemgetter
from collections import defaultdict

# 先把原始条目用列表+元组保存(避免字典覆盖)
raw_entries = [
    ('Bucky', 'Roberts'),
    ('Tom', 'Roberts'),
    ('Bernie', 'Zunks'),
    ('Jenna', 'Hayes'),
    ('Sally', 'Jones'),
    ('Amanda', 'Roberts'),
    ('Tom', 'Williams'),
    ('Dean', 'Hayes'),
    ('Bernie', 'Barbie'),
    ('Tom', 'Jones')
]

# 用defaultdict存储每个键对应的多个值
multi_value_dict = defaultdict(list)
for fname, lname in raw_entries:
    multi_value_dict[fname].append(lname)

# 展开成users列表
users = []
for fname, lnames in multi_value_dict.items():
    for lname in lnames:
        users.append({'fname': fname, 'lname': lname})

# 排序输出
for x in sorted(users, key=itemgetter('fname')):
    print(x)

这个方案适合需要先对同键的值做批量处理,再展开的场景。

小提示

虽然Python 3.7及以后的字典会保留插入顺序,但键的唯一性是所有Python版本字典的固有属性,所以只要用字典存重复键,就一定会出现覆盖丢失的问题。如果你的原始数据来自外部(比如文件、接口),一定要在读取阶段就用列表/元组保存,别直接转成字典。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 06:38:02