How to append/merge list of dictionaries?

房东的猫 提交于 2020-04-30 06:39:25

问题


I'm trying to merge some data between a single List of dictionaries that has lists inside. Merging would happen based on the "object" key if they matched. Also adding to their given "section" if the same value was matched. Given the following data:

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

I would like to achieve this as a end result

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)

Any pointers or help would be greatly appreciated. So far I am looping through each k,v pair in the dict's but cant wrap my head around matching between the two in the loop.


回答1:


try this one:

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



回答2:


Below code will do the task for you but please note that this may not be the most time-optimal way to do this and you may run into some key errors if you won't have the keys in all dicts consistent all over. Also you lose data if key semver as a different value in dicts matching values for 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)

Output

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


来源:https://stackoverflow.com/questions/61374241/how-to-append-merge-list-of-dictionaries

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!