python структура данных: список от одного до одного - PullRequest
1 голос
/ 12 марта 2020

У меня есть структура данных. Это выглядит следующим образом:

data = [[{'id': '1', 'name': 'parent', 'steps': 0},
 {'id': '2A', 'name': 'child', 'steps': 1},
 {'id': '3A', 'name': 'grandChild-A', 'steps': 2}],

[{'id': '1', 'name': 'parent', 'steps': 0},
 {'id': '2A', 'name': 'child', 'steps': 1},
 {'id': '3B', 'name': 'grandChild-B', 'steps': 2}],

[{'id': '1', 'name': 'parent', 'steps': 0},
 {'id': '2B', 'name': 'child', 'steps': 1},
 {'id': '3A', 'name': 'grandChild-C', 'steps': 2}],

[{'id': '1', 'name': 'parent', 'steps': 0},
 {'id': '2B', 'name': 'child', 'steps': 1},
 {'id': '3B', 'name': 'grandChild-D', 'steps': 2}],

[{'id': '1', 'name': 'parent', 'steps': 0},
 {'id': '2B', 'name': 'child', 'steps': 1},
 {'id': '3C', 'name': 'grandChild-E', 'steps': 2},
 {'id': '4A', 'name': 'final', 'steps': 3}
 ],

[{'id': '1', 'name': 'parent', 'steps': 0},
 {'id': '2', 'name': 'child', 'steps': 1},
 ]
]

Как мой ожидаемый результат равен

Ожидаемый результат

output = {
    "1" : {
        "2A": {
            "3A": "grandChild-A",
            "3B": "grandChild-B"

        },
        "2B": {
            "3A": "grandChild-C",
            "3B": "grandChild-D",
            "3C": {
                "4A": "final"
            }

        },
        "2":"child"

    }
}

Как я могу это сделать? Я хотел использовать перечислитель, но у меня всегда все внутри 1. Заранее спасибо

Обновление:

Я пробовал следующий код:

parent = data[0][0]["id"]
dict_new = {}
dict_new[parent] = {}

for e in data:
    for idx, item in enumerate(e):
        display(item)
        if idx>0:
            dict_new[parent][e[idx]["id"]] = e[idx]["name"]

Ответы [ 2 ]

2 голосов
/ 12 марта 2020

Вы можете попробовать:

d = {}
root = d
for L in data:
    d = root
    for M in L[:-1]:
        d = d.setdefault(M["id"], {})
    d[L[-1]["id"]] = L[-1]['name']

Идея состоит в том, чтобы следовать каждому списку, чтобы построить дерево (таким образом, d.setdefault(M["id"], {}). Лист обрабатывается по-разному, потому что это должно быть значение 'name' .

from pprint import pprint
pprint(root)

Вывод:

{'1': {'2': 'child',
       '2A': {'3A': 'grandChild-A', '3B': 'grandChild-B'},
       '2B': {'3A': 'grandChild-C',
              '3B': 'grandChild-D',
              '3C': {'4A': 'final'}}}}

Приведенное выше решение не будет работать для следующего ввода:

data = [[{'id': '1', 'name': 'parent', 'steps': 0},
 {'id': '2B', 'name': 'child', 'steps': 1}]],

[{'id': '1', 'name': 'parent', 'steps': 0},
 {'id': '2B', 'name': 'child', 'steps': 1},
 {'id': '3A', 'name': 'grandChild-C', 'steps': 2}]]

Итерация по второму списку попытается добавить новый элемент 3A -> grandChild-C к диктовке d['1']['2B']. Но d['1']['2B'] здесь не дикт, а строка 'child' из-за первого списка.

Когда мы перебираем элементы, мы проверяем, сопоставлен ли уже ключ, и в противном случае создаем новый dict (это задание setdefault). Мы также можем проверить, сопоставлен ли ключ с str, и если это в этом случае заменить строку на fre sh новый dict:

...
for M in L[:-1]:
    if M["id"] not in d or isinstance(d[M["id"]], str):
        d[M["id"]] = {}
    d = d[M["id"]]
...

Вывод:

{'1': {'2B': {'3A': 'grandChild-C'}}}
1 голос
/ 12 марта 2020

Я исправил ваши данные: (пропущена запятая)

data = [[{'id': '1', 'name': 'parent', 'steps': 0},
 {'id': '2A', 'name': 'child', 'steps': 1},
 {'id': '3A', 'name': 'grandChild-A', 'steps': 2}],

[{'id': '1', 'name': 'parent', 'steps': 0},
 {'id': '2A', 'name': 'child', 'steps': 1},
 {'id': '3B', 'name': 'grandChild-B', 'steps': 2}],

[{'id': '1', 'name': 'parent', 'steps': 0},
 {'id': '2B', 'name': 'child', 'steps': 1},
 {'id': '3A', 'name': 'grandChild-C', 'steps': 2}],

[{'id': '1', 'name': 'parent', 'steps': 0},
 {'id': '2B', 'name': 'child', 'steps': 1},
 {'id': '3B', 'name': 'grandChild-D', 'steps': 2}],

[{'id': '1', 'name': 'parent', 'steps': 0},
 {'id': '2B', 'name': 'child', 'steps': 1},
 {'id': '3C', 'name': 'grandChild-E', 'steps': 2},
 {'id': '4A', 'name': 'final', 'steps': 3}
 ],

[{'id': '1', 'name': 'parent', 'steps': 0},
 {'id': '2', 'name': 'child', 'steps': 1},
 ]
]

И я придумал этот код:

output = {}
#print(data)

for lis in data:
    o = output
    ln = len(lis) - 1
    for idx,d in enumerate(lis):
        id = d['id']
        if idx == ln:
            o[id] = d['name']
        else:
            if id not in o:
                o[id] = {}
            o = o[id]

print('Result:')
print(output)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...