Преобразование списка узлов во вложенный dict в python

У меня есть список dicts в python, который представляет список смежности, и я хочу преобразовать этот список во вложенный python dict. клавишами name и children.

Список узлов

Это пример списка диктов, это 10 первых элементов списка. Оригинал содержит 1000 элементов.

[{'id': 1, 'name': 'External sector', 'parent_id': 0},
 {'id': 3, 'name': 'Capital and financial markets', 'parent_id': 0},
 {'id': 77, 'name': 'Credit indicators', 'parent_id': 0},
 {'id': 15, 'name': 'Economic activity', 'parent_id': 0},
 {'id': 17, 'name': 'Monetary indicators', 'parent_id': 0},
 {'id': 30, 'name': 'Regional economy', 'parent_id': 0},
 {'id': 114, 'name': 'International economy', 'parent_id': 0},
 {'id': 157, 'name': 'National private financial system', 'parent_id': 0},
 {'id': 176, 'name': 'Financial Stability', 'parent_id': 0},
 {'id': 222, 'name': 'Financial Inclusion', 'parent_id': 0}]

Что я пробовал

Я нашел эту функцию в SO, которая может преобразовать этот список диктов во вложенный python dict:

def list_to_tree(data):
    out = { 
#         0: { 'id': 0, 'parent_id': 0, 'name': "Root node", 'sub': [] }
    }

    for p in data:
        out.setdefault(p['parent_id'], { 'sub': [] })
        out.setdefault(p['id'], { 'sub': [] })
        out[p['id']].update(p)
        out[p['parent_id']]['sub'].append(out[p['id']])

    return out[0]

Эта функция создает диктовки следующим образом:

{'id': 0,
 'name': 'rootnode',
 'parent_id': None,
 'sub': [{'id': 1,
          'name': 'External sector',
          'parent_id': 0,
          'sub': [{'id': 2,
                   'name': 'Exchange rates',
                   'parent_id': 1,
                   'sub': [{'id': 242,
                            'name': 'Controlled or free rates',
                            'parent_id': 2,
                            'sub': []},
                           {'id': 243,
                            'name': 'Floating rates',
                            'parent_id': 2,
                            'sub': []},
                           {'id': 532,
                            'name': 'Real and effective exchange rate indices',
                            'parent_id': 2,
                            'sub': []},
                           {'id': 533,
                            'name': 'Foreign exchange and wage indicators',
                            'parent_id': 2,
                            'sub': []},
                           {'id': 548,
                            'name': 'Average of period',
                            'parent_id': 2,
                            'sub': []},

Но я хотел создавать диктовки таким образом, без идентификатора

{
 'name': 'rootnode',
 'children': [{
          'name': 'External sector',
          'children': [{
                   'name': 'Exchange rates',
                   'children': [{
                            'name': 'Controlled or free rates',
                            'children': []},
                           {
                            'name': 'Floating rates',
                            'children': []},
                           {
                            'name': 'Real and effective exchange rate indices',
                            'children': []},
                           {
                            'name': 'Foreign exchange and wage indicators',
                            'children': []},
                           {
                            'name': 'Average of period',
                            'children': []},

Есть ли способ изменить эту функцию, которую я нашел, чтобы получить желаемый результат? Любая подсказка, подсказка или совет более чем приветствуются.


person Occhima    schedule 24.03.2021    source источник


Ответы (1)


Вы можете использовать функцию с небольшими изменениями:

  • Используйте клавишу «дети» вместо «суб»
  • Инициализируйте корневой узел только теми ключами, которые вы хотите иметь (имя и дочерние элементы)
  • Вместо вызова .update (который копирует все ключи) назначьте только ключ "имя"
def list_to_tree(data):
    out = { 
        0: { 'name': 'rootnode', 'children': [] }
    }

    for p in data:
        out.setdefault(p['parent_id'], { 'children': [] })
        out.setdefault(p['id'], { 'children': [] })
        out[p['id']]['name'] = p['name']
        out[p['parent_id']]['children'].append(out[p['id']])

    return out[0]
person trincot    schedule 24.03.2021
comment
ты спас меня, не знаю как тебя отблагодарить - person Occhima; 25.03.2021
comment
Всегда приятно читать, что ответ был полезен! - person trincot; 25.03.2021