【问题标题】:Merging Dicts that have Lists of Dicts in Python 2.7在 Python 2.7 中合并具有字典列表的字典
【发布时间】:2016-09-01 18:34:15
【问题描述】:

我正在尝试在 Python 中合并两个 dicts,它们可能是相同的,或者一个可能有更少的信息

例如

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]

keyCheck 只检查一个键是否在字典中,所以它不会抛出错误。

【问题讨论】:

  • 你确定masterdaily 是字典,这里字典中的每个值都是一个字符串或一个列表,并且每个列表中只有一个条目是字典吗?您确定会遵循这一点,因此不需要进行错误检查吗?
  • 不是每个值都会是一个列表,但有些是。有什么我对字典不了解的地方吗?它们不能为每个键设置不同类型的值吗?总的来说,我对 python 和字典还很陌生。
  • 字典确实可以为每个键具有不同类型的值:您的示例同时使用字符串和列表作为值,正如我在评论中指出的那样。我问是因为如果您确定数据遵循与您的示例相同的模式,您的答案代码会更简单。

标签: python python-2.7 dictionary


【解决方案1】:

这是一个使用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}

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

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

【讨论】:

  • 感谢您的帮助!即使处理大量数据也能完美运行!
【解决方案2】:

这是一个递归解决方案。虽然它无法与 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

【讨论】:

    猜你喜欢
    • 2014-07-28
    • 1970-01-01
    • 1970-01-01
    • 2012-08-11
    • 2012-07-17
    • 2021-11-26
    • 2021-10-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多