如何最好地合并多个词典中的值?

时间:2018-11-01 21:59:05

标签: python dictionary merge concatenation

我创建了一个函数,该函数接受字典的多个参数,并返回一个串联的字典。我在网上研究了一下合并合并字典的时间,并测试了有趣的字典。它们都导致更新值(或覆盖它们)。

我的用例是传入字典,其中每个键都有一个值,并希望使用具有相同或不同键的字典,以及每个键的值列表。这就是我对字典的所谓“串联”的外观的定义。

这是两个非常基本的字典:

a = {1: 'a', 2: 'b', 3: 'c'}
b = {1: 'd', 2: 'e', 3: 'f'}

功能如下:

def merge_dict(*args:dict):

    result = {}

    for arg in args:

        if not isinstance(arg, dict):
            return {}

        result_keys = result.keys()
        for key, value in arg.items():
            if key not in result_keys:
                result[key] = [value]
            else:
                result[key].append(value)

    return result

输出为:

print(merge_dict(a, b))
{1: ['a', 'd'], 2: ['b', 'e'], 3: ['c', 'f']}

我可以对元组或数组,Numpy数组等执行相同的操作。请注意,此函数非常简单,除了作为dict实例之外,它不清理输入或验证数据结构。

但是,我想知道是否有一种更有效或“ pythonic”的方式来做到这一点。请随时添加您的输入。

考虑使用不同的键添加这些字典:

c = {4: 'g', 5: 'h', 6: 'i'}
d = {4: 'j', 5: 'k', 6: 'l'}

输出为:

print(merge_dict(a, b, c, d))
{1: ['a', 'd'], 2: ['b', 'e'], 3: ['c', 'f'], 4: ['g', 'j'], 5: ['h', 'k'], 6: ['i', 'l']}

我将很快处理嵌套数据结构。

由于您的回答,这就是我所做的:

import collections

def merge_dicts_1(*args):
    rtn = collections.defaultdict(list)
    for input_dict in args:
        for key, value in input_dict.items():
            rtn[key].append(value)
    return rtn

def merge_dicts_2(*args):
    rtn = {}
    for input_dict in args:
        for key, value in input_dict.items():
            rtn.setdefault(key, []).append(value)
    return rtn

if __name__ == "__main__":
    a = {1: 'a', 2: 'b', 3: 'c'}
    b = {1: 'd', 2: 'e', 3: 'f'}
    c = {4: 'g', 5: 'h', 6: 'i'}
    d = {4: 'j', 5: 'k', 6: 'l'}
    e = merge_dicts_1(a, b, c, d)
    f = merge_dicts_2(a, b, c, d)
    print(e)
    print(f)
    print(e == f)

这将打印以下内容:

defaultdict(<class 'list'>, {1: ['a', 'd'], 2: ['b', 'e'], 3: ['c', 'f'], 4: ['g', 'j'], 5: ['h', 'k'], 6: ['i', 'l']})
{1: ['a', 'd'], 2: ['b', 'e'], 3: ['c', 'f'], 4: ['g', 'j'], 5: ['h', 'k'], 6: ['i', 'l']}
True

谢谢!

2 个答案:

答案 0 :(得分:2)

类似的方法适用于任意数量的输入词典:

import collections

def merge_dicts(*args):
    rtn = collections.defaultdict(list)
    for input_dict in args:
        for key, value in input_dict.items():
            rtn[key].append(value)
    return rtn

诀窍是使用defaultdict结构在不存在新条目时自动进行创建。在这种情况下,访问尚不存在的密钥会将其创建为空列表。

请注意,以上代码返回了defaultdict对象。如果不希望这样做,则可以将其转换回dict或改用以下函数:

def merge_dicts(*args):
    rtn = {}
    for input_dict in args:
        for key, value in input_dict.items():
            rtn.setdefault(key, []).append(value)
    return rtn

答案 1 :(得分:1)

这样的事情怎么样?

/Library/Java/JavaVirtualMachines/1.8.144_1_openJDK_macosx.jdk/Contents/Home

输出:

from functools import reduce

def _merge_two_dicts(combined, dictionary):
    for key, value in dictionary.items():
        combined.setdefault(key, []).append(value)
    return combined

def merge_dicts(*dicts):
    return reduce(_merge_two_dicts, dicts, {})


if __name__ == '__main__':
    a = {1: 'a', 2: 'b', 3: 'c'}
    b = {1: 'd', 2: 'e', 3: 'f', 4: 'g'}
    c = {1: 'h', 3: 'i', 5: 'j'}

    combined = merge_dicts(a, b, c)
    print(combined)