Создайте иерархические данные с помощью Python.на основе списка результатов - PullRequest
0 голосов
/ 28 января 2019

Мне нужно преобразовать списки данных в иерархический вложенный словарь в Python.Структура (отец - ребенок).

Это мои данные.

list_data = [
       {
           "id": 2,
           "father_id": 0,
           "desc": "Oficial de Negocios Senior",
           "name": "PEDRO MARTIN SOTO ROSALES"
       },
       {
           "id": 4,
           "father_id": 2,
           "desc": "Ejecutivo comercial",
           "name": "Adriana Paredez"
       },
       {
           "id": 5,
           "father_id": 2,
           "desc": "Ejecutivo comercial",
           "name": "Hugo Miranda"
       },
       {
           "id": 3,
           "father_id": 2,
           "desc": "Ejecutivo comercial",
           "name": "Mario Azcona"
       },
           {
                  "id": 6,
                  "father_id": 3,
                  "desc": "vendedor",
                  "name": "Diana Diaz"
              }
      ]

Я уже пытался использовать эту рекурсивную функцию, и я правильно понял структуру, но она объединяет еще 2 копии первых трех дочерних элементов, что мне действительно не нужно.Корневым отцом является элемент со значением Father_id = 0

def build(loc_key):

    children = {row['id']: {'name': row['name'], 'desc': row['desc'],
                                'child':[]} for row in list_data if row['father_id'] == loc_key}

    data = {}

    for key, value in children.items():
        data[key] = value
        for item in list_data:
            if item['father_id'] == key:
                data[key]['child'].append(build(key))
    return data

print(build(0))

Это в основном то, что мне нужно, чтобы получить

data = {
       2: {'desc': 'Oficial de Negocios Senior',
          'name': 'PEDRO MARTIN SOTO ROSALES', 
          'child': 
              [
              {3: {'desc': 'Ejecutivo comercial', 
                  'name': 'Mario Azcona', 
                  'child': [
                            {6: {'desc': 'vendedor', 
                                'name': 'Diana Diaz', 
                                 'child': []}}]}, 
              4: {'desc': 'Ejecutivo comercial', 
                 'name': 'Adriana Paredez', 
                 'child': []}, 
              5: {'desc': 'Ejecutivo comercial', 
                 'name': 'Hugo Miranda', 
                 'child': []}

PD: мне нужно поддерживать его динамически, потому что пользователиможно добавлять детей в базу данных.

1 Ответ

0 голосов
/ 28 января 2019

Я думаю, что проблема заключается в том, что ваша функция build принимает в качестве входных данных список узлов, а не работает на отдельных узлах попарно или каким-либо другим способом «меньшего списка».Поэтому рекурсия здесь не имеет смысла.OTOH, как только вы построили дерево (кстати, вы пытаетесь построить дерево), тогда рекурсия будет очень полезна при разборе получившейся структуры.Тем не менее, это не очень полезно для построения дерева.

Вот один из способов, которым вы можете построить дерево.Это O(n) вычисляет время и память, но сохраняет в действии еще пару копий списка, поэтому возможна некоторая оптимизация.

import pprint

list_data = [
       {
           "id": 2,
           "father_id": 0,
           "desc": "Oficial de Negocios Senior",
           "name": "PEDRO MARTIN SOTO ROSALES"
       },
       {
           "id": 4,
           "father_id": 2,
           "desc": "Ejecutivo comercial",
           "name": "Adriana Paredez"
       },
       {
           "id": 5,
           "father_id": 2,
           "desc": "Ejecutivo comercial",
           "name": "Hugo Miranda"
       },
       {
           "id": 3,
           "father_id": 2,
           "desc": "Ejecutivo comercial",
           "name": "Mario Azcona"
       },
       {
           "id": 6,
           "father_id": 3,
           "desc": "vendedor",
           "name": "Diana Diaz"
       }
]

def tree_structure(list_data):
    #build the requisite data structure in a "flat" way... you can initialize this "as you go" in the loop below if more optimization is needed.
    data = {row["id"]: {"desc": row["desc"], "name": row["name"], "child": {}} for row in list_data}
    root_id = None
    for row in list_data:
        if row["father_id"] != 0:
            data[row["father_id"]]["child"][row["id"]] = data[row["id"]] #note that this stores only a reference to the child dictionary, so it is O(1) memory
        else:
            root_id = row["id"] #we need this later
    return {root_id: data[root_id]}

pprint.pprint(tree_structure(list_data))
...