Как добавить / объединить список словарей? - PullRequest
0 голосов
/ 22 апреля 2020

Я пытаюсь объединить некоторые данные между одним списком словарей, в котором есть списки. Слияние будет происходить на основе ключа «объект», если они совпадают. Также добавляем к их данному «разделу», если совпадает одно и то же значение. Учитывая следующие данные:

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 в dict, но не могу обернуть мою голову вокруг соответствия между двумя в l oop.

Ответы [ 2 ]

2 голосов
/ 22 апреля 2020

попробуйте это:

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
1 голос
/ 22 апреля 2020

Нижеприведенный код выполнит эту задачу за вас, но учтите, что это может быть не самый оптимальный по времени способ сделать это, и вы можете столкнуться с некоторыми ключевыми ошибками, если у вас не будет согласованных ключей во всех диктовках во всем , Кроме того, вы потеряете данные, если ключ 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"
            }
        ]
    }
]
...