如何将具有相同键的字典合并?

13

我有一个类似于这样的字典列表:

dicts = [
    {'key_a': valuex1,
     'key_b': valuex2,
     'key_c': valuex3},

    {'key_a': valuey1,
     'key_b': valuey2,
     'key_c': valuey3},

    {'key_a': valuez1,
     'key_b': valuez2,
     'key_c': valuez3}
]
我想将它们取出来并构建一个大字典,如下所示:
big_dict = {
    'key_a': [valuex1, valuey1, valuez1],
    'key_b': [valuex2, valuey2, valuez2],
    'key_c': [valuex3, valuey3, valuez3]
}
有没有一种优雅的方法像 "zip" 一样,让我做到这一点?
所有键总是相同的。
5个回答

16
big_dict = {}
for k in dicts[0]:
    big_dict[k] = [d[k] for d in dicts]

或者,使用字典推导式

{k: [d[k] for d in dicts] for k in dicts[0]}

3
只需添加一个细节,以避免在任何子字典没有所有键时出现KeyError:{k:[d [k] for d in results if k in d.keys()] for k in results [0]} - Ricardo Guerreiro

5
你可以使用 collections.defaultdict。这种解决方案的好处是它不需要字典中的键保持一致,同时仍然保持最小 O(n) 时间复杂度。
from collections import defaultdict

dict_list = [{'key_a': 'valuex1', 'key_b': 'valuex2', 'key_c': 'valuex3'},
             {'key_a': 'valuey1', 'key_b': 'valuey2', 'key_c': 'valuey3'},
             {'key_a': 'valuez1', 'key_b': 'valuez2', 'key_c': 'valuez3'}]            

d = defaultdict(list)
for myd in dict_list:
    for k, v in myd.items():
        d[k].append(v)

结果:

print(d)

defaultdict(list,
            {'key_a': ['valuex1', 'valuey1', 'valuez1'],
             'key_b': ['valuex2', 'valuey2', 'valuez2'],
             'key_c': ['valuex3', 'valuey3', 'valuez3']})

2
如果所有字典都有相同的键集,那么这将起作用: ```

如果所有字典都有相同的键集,那么这将起作用:

```
dict((k, [d[k] for d in dictList]) for k in dictList[0])

如果它们可能有不同的键,您需要首先通过对各个字典的键进行集合并来构建一组键:
allKeys = reduce(operator.or_, (set(d.keys()) for d in dictList), set())

那么您需要保护一些字典中缺失键的情况:

dict((k, [d[k] for d in [a, b] if k in d]) for k in allKeys)

4
你可以使用字典推导式: {k: [d[k] for d in dictList] for k in dictList[0]}。它可以帮助你轻松地从一个由多个字典组成的列表中提取出特定键所对应的值,并将其组合成一个新的字典。 - Blender
是的,如果你使用的是支持字典推导的Python版本。我自己使用的是2.6版本,所以没有这个功能。 - BrenBarn
一个字典推导式在语法上等同于一个生成器表达式,其中{key: value ...}被替换为dict((key, value)...),这在2.6版本中也是有效的。 - Joel Cornett

0
如果您愿意使用第三方库,可以使用Pandas。 pd.DataFrame 构造函数可以直接接受一个字典列表:
import pandas as pd

res = pd.DataFrame(dictList).to_dict(orient='list')

{'key_a': ['valuex1', 'valuey1', 'valuez1'],
 'key_b': ['valuex2', 'valuey2', 'valuez2'],
 'key_c': ['valuex3', 'valuey3', 'valuez3']}

-1
您可以按照以下方式合并字典:
def merge_dicts(dict_list, separator=''):
    """
    Merges list of dictionaries to a single dictionary, Concatenates values with the same key.
    :param dict_list: list of dictionaries to be merged.
    :param separator: separator to be inserted between values of same key.
    :return: Merged dictionary.
    """
    return {k1: separator.join([d[k1] for d in dict_list if k1 in d])
            for k1 in set(reduce(lambda x, y: x+y, [k.keys() for k in dict_list]))
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接