【问题标题】:Transform data with level column in python在 python 中使用级别列转换数据
【发布时间】:2023-02-24 00:32:32
【问题描述】:

我有这样的数据代表分层树结构:

[
    {
        "level":0,
        "name":"python"
    },
    {
        "level":1,
        "name":"food"
    },
    {
        "level":2,
        "name":"banana"
    },
    {
        "level":3,
        "name":"protein"
    },
    {
        "level":2,
        "name":"apple"
    },
    {
        "level":1,
        "name":"fuel"
    }
]

我想把它改造成:

[
    {
        "level":0,
        "name":"python",
        "children":[
            {
                "level":1,
                "name":"food",
                "children":[
                    {
                        "level":2,
                        "name":"banana",
                        "children":[
                            {
                                "level":3,
                                "name":"protein",
                                "children":[
                                    
                                ]
                            }
                        ]
                    },
                    {
                        "level":2,
                        "name":"apple",
                        "children":[
                            
                        ]
                    }
                ]
            },
            {
                "level":1,
                "name":"fuel",
                "children":[
                    
                ]
            }
        ]
    }
]

我正在使用 python,并且更喜欢使用或不使用外部库(甚至使用 pandas)的 python 中的解决方案。我很想看到解决方案,提前谢谢你:)

【问题讨论】:

    标签: python json pandas dataframe dictionary


    【解决方案1】:

    这是一种方法:

    def create_tree(nodes):
        # add parent information to each node
        for i, node in enumerate(nodes):
            if node['level'] == 0:
                node['parent'] = None
            else:
                j = i - 1
                while j >= 0:
                    if nodes[j]['level'] < node['level']:
                        node['parent'] = nodes[j]['name']
                        break
                    j -= 1
        
        
        node_dict = {}
        for node in nodes:
            node_dict[node['name']] = node
        
        for node in nodes:
            parent_name = node.get('parent')
            if parent_name is not None:
                parent = node_dict[parent_name]
                if 'children' not in parent:
                    parent['children'] = []
                parent['children'].append(node)
        
        for node in nodes:
            if node.get('parent') is None:
                return node
        return None
    
    nodes = [
        {"level":0,"name":"python"},
        {"level":1,"name":"food"},
        {"level":2,"name":"banana"},
        {"level":3,"name":"protein"},
        {"level":2,"name":"apple"},
        {"level":1,"name":"fuel"}
    ]
    
    tree = create_tree(nodes)
    
    print(tree)
    
    
    

    这给了你想要的

    {'level': 0, 'name': 'python', 'parent': None, 'children': [{'level': 1, 'name': 'food', 'parent': 'python', 'children': [{'level': 2, 'name': 'banana', 'parent': 'food', 'children': [{'level': 3, 'name': 'protein', 'parent': 'banana'}]}, {'level': 2, 'name': 'apple', 'parent': 'food'}]}, {'level': 1, 'name': 'fuel', 'parent': 'python'}]}
    

    【讨论】:

      【解决方案2】:

      我想你列表中字典的顺序很重要,否则我不知道孩子应该列在哪个父母之下。我建议编写一个递归函数来获取 n 级的最后一个元素并将子元素附加到那里:

      import json
      
      input_list = [
          {
              "level":0,
              "name":"python"
          },
          {
              "level":1,
              "name":"food"
          },
          {
              "level":2,
              "name":"banana"
          },
          {
              "level":3,
              "name":"protein"
          },
          {
              "level":2,
              "name":"apple"
          },
          {
              "level":1,
              "name":"fuel"
          }
      ]
      
      def get_last_elt_at_lvl(rec, lvl):
          if lvl == 0:
              return rec[-1]
          else:
              for i in range(len(rec)-1,-1,-1):
                  if rec[i]['children']:
                      r = get_last_elt_at_lvl(rec[-1]['children'], lvl-1)
                      if r:
                          return r
          return None
      
      output_list = []
      for d in input_list:
          if d["level"] == 0:
              output_list.append(d)
          else:
              last_elt = get_last_elt_at_lvl(output_list, d["level"]-1)
              children = last_elt.setdefault('children', [])
              children.append(d)
      
      print(json.dumps(output_list, indent=4))
      

      输出:

      [
          {
              "level": 0,
              "name": "python",
              "children": [
                  {
                      "level": 1,
                      "name": "food",
                      "children": [
                          {
                              "level": 2,
                              "name": "banana",
                              "children": [
                                  {
                                      "level": 3,
                                      "name": "protein"
                                  }
                              ]
                          },
                          {
                              "level": 2,
                              "name": "apple"
                          }
                      ]
                  },
                  {
                      "level": 1,
                      "name": "fuel"
                  }
              ]
          }
      ]
      

      【讨论】:

        猜你喜欢
        • 2018-02-11
        • 1970-01-01
        • 1970-01-01
        • 2012-12-31
        • 1970-01-01
        • 1970-01-01
        • 2023-01-18
        • 1970-01-01
        • 2022-06-16
        相关资源
        最近更新 更多