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

Python 如何从含重复键的列表生成保留所有值的分组字典?

重复键值对分组聚合的字典实现

给定两个一一对应的平行列表:

keys = ['a', 'b', 'c', 'c']
values = [1, 2, 3, 4]

日常常用的字典构造写法dictionary = dict(zip(keys, values)),会利用Python字典键唯一的特性,自动覆盖重复键的旧值,最终运行结果为{'a': 1, 'b': 2, 'c': 4},直接丢失了键为c的第一个对应值3。
我们实际需要的输出效果为{'a': 1, 'b': 2, 'c': [3,4]}——即对相同键对应的所有值做分组存储,不丢弃任何原始配对数据。这类需求完全可以通过遍历配对、按需聚合的方式实现,常用的实现方案有以下两种:

方案1:无依赖基础遍历实现

逐一遍历zip打包的键值对,针对每个键的出现状态做判断:

  • 键首次出现时,直接保存对应的原始值
  • 键已存在时,先检查当前存储值是否为列表,非列表则先将原有值转为列表,再追加新值
result = {}
for k, v in zip(keys, values):
    if k not in result:
        result[k] = v
    else:
        # 单值转列表,方便后续追加新值
        if not isinstance(result[k], list):
            result[k] = [result[k]]
        result[k].append(v)

print(result) # 输出: {'a': 1, 'b': 2, 'c': [3, 4]}

方案2:基于collections模块的简化实现

借助内置的defaultdict省去手动判断键是否存在的重复逻辑,最后再对聚合结果做格式转换,匹配“单值存原值、多值存列表”的要求:

from collections import defaultdict

# 先按列表收集每个键对应的所有值
temp_result = defaultdict(list)
for k, v in zip(keys, values):
    temp_result[k].append(v)

# 格式转换:仅出现一次的键直接取原始值,重复出现的保留值列表
result = {
    k: val[0] if len(val) == 1 else val
    for k, val in temp_result.items()
}

print(result) # 输出: {'a': 1, 'b': 2, 'c': [3, 4]}

如果业务场景允许所有值统一以列表形式存储(比如后续需要批量遍历所有值的场景),可以直接省去结果转换的步骤,代码会更简洁。

实现注意事项

  • 常规dict(zip(...))的覆盖逻辑是Python字典的核心特性,重复键只会保留最后一次出现的对应值,这就是初始示例中丢失数据的根本原因。
  • 聚合过程中一定要做好值的类型判断,避免把仅出现一次的键值误转成单元素列表,导致后续业务处理出现类型不兼容的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.25 21:36:10