Python 根据id将json列表嵌套

Python 根据id将json列表嵌套,python,json,nested,Python,Json,Nested,如何按id对JSON对象进行分组,以在Python中生成嵌套的JSON? JSON的结构如下: [{ "id": "4", "title": "Part 4", "children": {} },{ "id": "4.1.", "title": "Section 4.1. T

如何按id对JSON对象进行分组,以在Python中生成嵌套的JSON? JSON的结构如下:

  [{
    "id": "4",
    "title": "Part  4",
    "children": {}
  },{
    "id": "4.1.",
    "title": "Section  4.1.  Transition Rule",
    "children": {}
  },
  {
    "id": "4.1.1.",
    "title": "4.1.1.  Transition, January 2014",
    "children": {}
  },
  {
    "id": "4.1.1.1.",
    "title": "4.1.1.1.  Transition Rule",
    "children": {}
  },
  {
    "id": "4.1.2.",
    "title": "4.1.2.  Transition, January 2015",
    "children": {}
  },
  {
    "id": "4.1.2.1.",
    "title": "4.1.2.1.  Transition Rule",
    "children": {}
  },
]]
目标是建立一个树结构,其中每个对象(部分)包含从4到4.1>4.1.1>4.1.1.1的所有子部分。
所需输出的片段如下所示:

[
   {
      "id":"4",
      "title":"Part  4",
      "children":{
         {
            "id":"4.1.",
            "title":"Section  4.1.  Transition Rule",
            "children":{
               {
                  "id":"4.1.1.",
                  "title":"4.1.1.  Transition, January 2014",
                  "children":{
                     {
                        "id":"4.1.1.1.",
                        "title":"4.1.1.1.  Transition Rule",
                        "children":{
                           
                        }
                     }
                  }
               },
               {
                  "id":"4.1.2.",
                  "title":"4.1.2.  Transition, January 2015",
                  "children":{
                     {
                        "id":"4.1.2.1.",
                        "title":"4.1.2.1.  Transition Rule",
                        "children":{
                           
                       
您可以使用递归:

from collections import defaultdict
def get_tree(d):
  _d, r = defaultdict(list), []
  for i in d:
     _d[i['key'][0]].append({**i, 'key':i['key'][1:]})
  for b in _d.values():
     j, k = [l for l in b if not l['key']], [l for l in b if l['key']]        
     if j:
        r.extend([{**{x:y for x, y in i.items() if x != 'key'}, 'children':get_tree(k)} for i in j])
     else:
        r.extend(get_tree(k))
  return r
  

data = [{'id': '4', 'title': 'Part  4', 'children': {}}, {'id': '4.1.', 'title': 'Section  4.1.  Transition Rule', 'children': {}}, {'id': '4.1.1.', 'title': '4.1.1.  Transition, January 2014', 'children': {}}, {'id': '4.1.1.1.', 'title': '4.1.1.1.  Transition Rule', 'children': {}}, {'id': '4.1.2.', 'title': '4.1.2.  Transition, January 2015', 'children': {}}, {'id': '4.1.2.1.', 'title': '4.1.2.1.  Transition Rule', 'children': {}}, {'id': '4.1.3.', 'title': '4.1.3.  Transition, January 2017', 'children': {}}]

输出:

[
  {
    "id": "4",
    "title": "Part  4",
    "children": [
        {
            "id": "4.1.",
            "title": "Section  4.1.  Transition Rule",
            "children": [
                {
                    "id": "4.1.1.",
                    "title": "4.1.1.  Transition, January 2014",
                    "children": [
                        {
                            "id": "4.1.1.1.",
                            "title": "4.1.1.1.  Transition Rule",
                            "children": []
                        }
                    ]
                },
                {
                    "id": "4.1.2.",
                    "title": "4.1.2.  Transition, January 2015",
                    "children": [
                        {
                            "id": "4.1.2.1.",
                            "title": "4.1.2.1.  Transition Rule",
                            "children": []
                        }
                    ]
                },
                {
                    "id": "4.1.3.",
                    "title": "4.1.3.  Transition, January 2017",
                    "children": []
                 }
             ]
          }
       ]
   }
]

请发布您的预期输出。感谢您的反馈。我正试图弄明白这一点,它适用于较小的数据集,但对于较大的数据集,它会抛出一个错误:文件“index.py”,第60行,在get_tree[I['key'].popleft()]中defined@arturshevtsov确保首先将
键添加到输入列表中的每个词典中。调用
get_tree
时,应该向它传递一个字典列表,其中包含一个由
集合组成的键。deque
存储id的组件:
[{**i,'key':deque([*filter(None,i['id'].split('.)])如果JSON包含重复的值,这种方法会失败吗?@arturshevtsov No,它只是将另一个元素添加到包含该id和所有子值的运行结果列表中。请注意:我刚刚删除了帖子中的
deque
用法,以简化原始
数据的形成。
[
  {
    "id": "4",
    "title": "Part  4",
    "children": [
        {
            "id": "4.1.",
            "title": "Section  4.1.  Transition Rule",
            "children": [
                {
                    "id": "4.1.1.",
                    "title": "4.1.1.  Transition, January 2014",
                    "children": [
                        {
                            "id": "4.1.1.1.",
                            "title": "4.1.1.1.  Transition Rule",
                            "children": []
                        }
                    ]
                },
                {
                    "id": "4.1.2.",
                    "title": "4.1.2.  Transition, January 2015",
                    "children": [
                        {
                            "id": "4.1.2.1.",
                            "title": "4.1.2.1.  Transition Rule",
                            "children": []
                        }
                    ]
                },
                {
                    "id": "4.1.3.",
                    "title": "4.1.3.  Transition, January 2017",
                    "children": []
                 }
             ]
          }
       ]
   }
]