Python中如何合并列表中字典相同键的值?

For example

d 合并后变成 new_d

d = [
 {1: [12, 24]},
 {1: [24, 36]},
 {2: [111,222]}
 ]

new_d = [ {1: [12, 24, 36]}, {2: [111, 222]} ]


Python中如何合并列表中字典相同键的值?
8 回复

既然是列表,貌似一般就是遍历了吧,用 set 来做字典的 value 。最后再遍历一次把 set 转换为列表。


def merge_dicts_in_list(dict_list):
    """
    合并列表中所有字典,相同键的值合并为列表
    如果字典中相同键的值不是列表,会自动转为列表
    """
    result = {}
    for d in dict_list:
        for key, value in d.items():
            if key in result:
                # 如果已存在该键,确保当前值是列表形式
                if not isinstance(result[key], list):
                    result[key] = [result[key]]
                # 添加新值(如果是列表则扩展,否则追加)
                if isinstance(value, list):
                    result[key].extend(value)
                else:
                    result[key].append(value)
            else:
                # 如果键不存在,直接赋值(如果是列表则保持,否则转为单元素列表)
                result[key] = value if isinstance(value, list) else [value]
    return result

# 测试示例
if __name__ == "__main__":
    # 示例1:基础合并
    data1 = [
        {"name": "Alice", "age": 25},
        {"name": "Bob", "age": 30},
        {"name": "Charlie", "age": 35}
    ]
    print("示例1结果:", merge_dicts_in_list(data1))
    # 输出: {'name': ['Alice', 'Bob', 'Charlie'], 'age': [25, 30, 35]}
    
    # 示例2:包含列表值
    data2 = [
        {"skills": ["Python", "Java"], "level": "Senior"},
        {"skills": ["JavaScript"], "level": "Mid"},
        {"skills": ["Go", "Rust"], "level": "Junior"}
    ]
    print("示例2结果:", merge_dicts_in_list(data2))
    # 输出: {'skills': ['Python', 'Java', 'JavaScript', 'Go', 'Rust'], 'level': ['Senior', 'Mid', 'Junior']}
    
    # 示例3:混合类型处理
    data3 = [
        {"id": 1001, "tags": "backend"},
        {"id": 1002, "tags": ["frontend", "ui"]},
        {"id": 1003, "tags": "devops"}
    ]
    print("示例3结果:", merge_dicts_in_list(data3))
    # 输出: {'id': [1001, 1002, 1003], 'tags': ['backend', 'frontend', 'ui', 'devops']}

这个函数的核心逻辑是遍历列表中的每个字典,然后对每个键值对进行合并处理。关键点在于处理不同类型的值:当遇到已存在的键时,它会检查当前存储的值和新值是否为列表,并进行相应的列表合并操作;对于新键,则根据值类型决定是否包装为列表。这样能确保所有相同键的值都被收集到同一个列表中,无论原始数据是单个值还是列表。

如果只需要合并特定键,可以在函数内添加键过滤逻辑。

总结建议:根据实际需求选择是否保持原始值类型。

s = {k: set() for x in d for k,v in x.items()}
[s[k].update(v) for x in d for k,v in x.items()]
{k: list(v) for k,v in s.items()}

[ {id: val} for (id, val) in [[(new_d, new_d.update({k: new_d.get(k, set()).union(set(v))})) for (k, v) in m.items()] for m in d][0][0][0].items() ]

new_d = {}

另外一种思路,前提是 d 得排序好

from itertools import groupby, chain
[{k: [x for x, _ in groupby(sorted(chain(*[v[k] for v in g])))]} for k, g in groupby(d, lambda x: list(x.keys())[0])]

厉害了

回到顶部