【问题标题】:How to merge list of dictionaries?如何合并字典列表?
【发布时间】:2020-08-11 09:00:54
【问题描述】:

我在这里扩展我原来的问题:How to append/merge list of dictionaries?

我正在尝试在包含列表的单个字典列表之间合并一些数据。如果它们匹配,则合并将基于“object”和“semver”键进行。如果匹配相同的值,也会添加到他们给定的“部分”。给定以下数据:

data = [
        {
         "semver":"1.0.0",
         "sections":[
            {
               "name":"Add",
               "messages":[
                  "add: comment here"
               ]
            }
         ],
         "object":"files.sh"
      },
      {
         "semver":"1.0.0",
         "sections":[
            {
               "name":"Add",
               "messages":[
                  "add: Second comment here"
               ]
            }
         ],
         "object":"files.sh"
      },
      {
         "semver":"1.0.0",
         "sections":[
            {
               "name":"Fix",
               "messages":[
                  "Comment here"
               ]
            }
         ],
         "object":"files.sh"
      },
      {
         "semver":"2.0.0",
         "sections":[
            {
               "name":"Fix",
               "messages":[
                  "2.0.0 Fix Comment here"
               ]
            }
         ],
         "object":"files.sh"
      },
      {
         "semver":"2.0.0",
         "sections":[
            {
               "name":"Add",
               "messages":[
                  "2.0.0 Add Comment here"
               ]
            }
         ],
         "object":"files.sh"
      },
      {
         "semver":"2.0.0",
         "sections":[
            {
               "name":"Add",
               "messages":[
                  "2.0.0 comment for the NewFile"
               ]
            }
         ],
         "object":"NewFile.sh"
      },
]

我希望最终实现这一目标

data = [
        {
         "semver":"1.0.0",
         "sections":[
            {
               "name":"Add",
               "messages":[
                  "add: comment here",
                  "add: Second comment here"
               ]
            },
            {
               "name":"Fix",
               "messages":[
                  "Fix: comment here"
               ]
            }
         ],
         "object":"files.sh"
      },
        {
         "semver":"2.0.0",
         "sections":[
            {
               "name":"Add",
               "messages":[
                  "2.0.0 Add comment here",
               ]
            },
            {
               "name":"Fix",
               "messages":[
                  "2.0.0 Fix Comment here"
               ]
            }
         ],
         "object":"files.sh"
      },
      {
         "semver":"2.0.0",
         "sections":[
            {
               "name":"Add",
               "messages":[
                  "2.0.0 comment for the NewFile"
               ]
            }
         ],
         "object":"NewFile.sh"
      },

]

代码块

objects = {}  # mapping for object: object_data with sections
sections = defaultdict(list)  # mapping for object: all sections
for d in data:
    print(d["semver"])
    for k, v in list(d.items()):
        if v == d["semver"]:
            try:
                section = d.pop("sections")
                sections[d["object"]].extend(section)
                objects[d["object"]] = d  # populate with object data without sections
            except Exception as e:
                print(e)
                pass

output = []
for object_name, object_data in objects.items():
    object_data["sections"] = sections[object_name]
    output.append(object_data)

到目前为止,我正在循环遍历 dict 中的每个 k,v 对,但我无法理解这两个版本之间的匹配并在循环中附加到特定的 dict

【问题讨论】:

  • 澄清一下,您想连接sections 列表以获得objectsemver 的相同组合,对吗?
  • 是的,没错

标签: python list dictionary merge append


【解决方案1】:

有 2 个改动需要做:

  1. objectssections 中的键更改为基于由元组表示的objectsemver 的组合。
  2. 添加一个辅助功能来合并部分中的消息

试试这个:

import json  # just for pretty print, you don't have to use it
from collections import defaultdict


def merge_messages(sections):
    d = defaultdict(list)
    for m in sections:
        d[m["name"]].extend(m["messages"])
    return [{"name": k, "messages": v} for k, v in d.items()]


objects = {}  # mapping for data with sections for (object, semver) combinations
sections = defaultdict(list)  # mapping for sections data for (object, semver) combinations
for d in data:
    section = d.pop("sections")
    sections[(d["object"], d["semver"])].extend(section)  # extends the sections for the object
    objects[(d["object"], d["semver"])] = d  # # populate with object data without sections

# merge between sections and objects by object key
output = []
for comb, object_data in objects.items():
    object_data["sections"] = merge_messages(sections[comb])
    output.append(object_data)
print(json.dumps(output, indent=4))  # just for pretty print

【讨论】:

  • 我认为如果服务器和对象相同,OP 想要合并这些部分,如果名称相同,则合并消息。
  • 感谢 Gabip,正如@Bobby Ocean 提到的那样。如果原始名称相同,我也会尝试合并消息。我想这可以从代码中的(扩展)更改?
  • @Boojs 我已经更新了我的解决方案,请查看
猜你喜欢
  • 1970-01-01
  • 2021-07-29
  • 2020-08-06
  • 2016-01-02
  • 1970-01-01
  • 1970-01-01
  • 2019-03-12
  • 1970-01-01
相关资源
最近更新 更多