在Python 2.7中合并具有字典列表的字典

3
我是一个有用的助手,可以为您提供翻译。以下是您需要翻译的内容:

我正在尝试合并两个 Python 中的 dict,它们可能相同或者其中一个信息少得多。

例如:

master = {"a": 5564, "c": [{"d2":6}]}
daily = { "a": 795, "b": 1337, "c": [{"d1": 2,"d2": 2,"d3": [{"e1": 4,"e2": 4}]}]}

他们需要被合并,以便输出结果如下所示。
master = { "a": 6359, "b": 1337, "c": [{"d1": 2,"d2": 8,"d3": [{"e1": 4,"e2": 4}]}]}

虽然我只得到了null的返回值,但我还是尝试了一下。可能是我漏掉了什么或者完全错了。我就是想不出来。任何帮助都将不胜感激。谢谢。

def merge(master,daily):
    for k, v in daily.items():
        if isinstance(daily[k],list):
            key_check = keyCheck(k, master)
            if key_check:
                merge(master[k],daily[k])
            else :
                master[k] = daily[k]
        else :
            if keyCheck(k, master):
                 master[k] += daily[k]
            else :
                master[k] = daily[k]
< p > keyCheck 只检查字典中是否有该键,因此不会引发错误。< /p >

你确定 masterdaily 是字典类型,这里的每个值都是字符串或列表,并且每个列表恰好只有一个字典项吗?你确定这将被遵循,因此不需要进行错误检查吗? - Rory Daulton
并非每个值都是列表,但有些是。关于字典,我是否有什么不理解的地方,它们不能为每个键具有不同类型的值吗?我对Python和字典总体上都很新。 - Astrea
字典确实可以为每个键具有不同类型的值:正如我在评论中指出的那样,您的示例同时使用字符串和列表作为值。我之所以问这个问题,是因为如果您确定数据遵循与示例相同的模式,则您答案的代码可以更简单。 - Rory Daulton
2个回答

5

这里有一个使用 collections.Counter() 的一行式代码:

>>> from collections import Counter
>> C2 = Counter(daily)
>>> C1 = Counter(master)
>>> 
>>> {k:reduce(lambda x,y : Counter(x)+Counter(y), v) if isinstance(v, list) and k in (C1.viewkeys() & C2) else v for k, v in (C1 + C2).items()}
{'a': 6359, 'c': Counter({'d3': [{'e1': 4, 'e2': 4}], 'd2': 8, 'd1': 2}), 'b': 1337}

首先,您可以将字典转换为计数器对象,以便在对计数器求和后添加常见键的值(这就是计数器的add属性的工作方式),然后您可以循环遍历项目,对于同时存在于两个计数器中且其值为列表的键,您可以使用reduce()函数将相同算法应用于所有列表项。

如果您的列表包含另一个嵌套的类似数据结构,则可以将此代码转换为递归函数。


1
感谢您的帮助!即使处理大量数据,也能完美运行! - Astrea

1

这里是一个递归解决方案。虽然它无法与Kasramvd的答案相竞争。

def merge(dic1, dic2):

    merged = dict(dic1, **dic2) # Merge dictionaries without adding values. Just exchanging them.
                                # Similar to .update() but does not override subdicts.

    for key in merged:
        if key in dic1 and key in dic2:
            if isinstance(dic1[key], list):
                merged[key] = merge(dic1[key][0], dic2[key][0])
            else:
                merged[key] = dic1[key] + dic2[key]

    return merged

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