【问题标题】:How to append/merge list of dictionaries?如何附加/合并字典列表?
【发布时间】:2020-08-06 00:17:17
【问题描述】:

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

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"
      }
]

我希望最终实现这一目标

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"
      },
]

for item in data:
    for k, v  in item.items():
        print(k)
        print(v)

任何指针或帮助将不胜感激。到目前为止,我正在遍历字典中的每个 k,v 对,但无法将我的头脑围绕在循环中两者之间的匹配上。

【问题讨论】:

  • 您的编码尝试在哪里?请重复how to ask
  • 嘿@Prune,我只有一个数据循环,只是无法在循环中的两者之间进行匹配。刚刚用我目前拥有的内容更新了我的原始帖子。

标签: python list dictionary merge append


【解决方案1】:

试试这个:

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

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

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

【讨论】:

  • 谢谢@Gabip!这真的很有用。如果它们在列表中,我将尝试扩展它并尝试管理更多的 semver。也尝试合并部分而不是扩展。
  • 嘿@Gabip,有没有办法管理多个 semver 并扩展每个对象的每个部分?我正在尝试在数据下添加另一个 for 循环以扩展每个 semver,但得到一些奇怪的结果。任何帮助表示赞赏
  • @Boojs 我认为最好将其作为一个单独的问题提出。对您的帮助会更加清晰易懂。
  • 嘿@Gabip,感谢您的快速回复,这是新问题:stackoverflow.com/questions/61465107/…
【解决方案2】:

下面的代码将为您完成任务,但请注意,这可能不是执行此操作的最优化时间的方法,如果您的所有字典中的键不一致,您可能会遇到一些关键错误. 此外,如果键 semver 作为与 object 匹配值的字典中的不同值,您也会丢失数据

d = []
for x in data:
    for y in d:
        if x['object'] == y['object']:
            for section_x in x['sections']:
                for section_y in y['sections']:
                    if section_x['name'] == section_y['name']:
                        section_y['messages'].extend(x for x in\
                                section_x['messages'] if x not in section_y['messages'])
                        break
                else:
                    y['sections'].append(section_x)
            break
    else:
        d.append(x)

输出

[
    {
        "semver": "1.0.0",
        "object": "files.sh",
        "sections": [
            {
                "messages": [
                    "add: comment here",
                    "add: Second comment here"
                ],
                "name": "Add"
            },
            {
                "messages": [
                    "Comment here"
                ],
                "name": "Fix"
            }
        ]
    }
]

【讨论】:

    猜你喜欢
    • 2020-08-11
    • 1970-01-01
    • 2022-07-05
    • 1970-01-01
    • 2020-01-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-29
    相关资源
    最近更新 更多