【问题标题】:Create a hierarchichal data with python. based on a list of results使用 python 创建分层数据。基于结果列表
【发布时间】:2019-01-28 03:45:02
【问题描述】:

我需要在 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:我需要以动态方式支持它,因为用户可以在数据库中添加子项。

【问题讨论】:

    标签: python python-3.x dictionary data-structures hierarchical-data


    【解决方案1】:

    我认为问题在于您的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))
    

    【讨论】:

    • 请注意,pprint 打印 descnamechild 的顺序与您预期的输出顺序不同。这是因为字典没有内在顺序,并且生成的数据结构是相同的。
    • 是的@Scott。我用另一种方式解决了,但我认为这比我的方法更好
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-01-22
    • 1970-01-01
    • 2012-12-20
    • 2019-07-01
    • 1970-01-01
    • 2021-01-26
    • 1970-01-01
    相关资源
    最近更新 更多