Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/293.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
从python中的字典列表创建分层json转储_Python_Json_Flask - Fatal编程技术网

从python中的字典列表创建分层json转储

从python中的字典列表创建分层json转储,python,json,flask,Python,Json,Flask,下表: categories = Table("categories", metadata, Column("id", Integer, primary_key=True), Column("name", String), Column("parent_id", Integer, ForeignKey("categories.id"),

下表:

categories = Table("categories", metadata,
                   Column("id", Integer, primary_key=True),
                   Column("name", String),
                   Column("parent_id", Integer, ForeignKey("categories.id"),
                          CheckConstraint('id!=parent_id'), nullable=True),

)
一个类别可以有多个子类别,但只有一个父类别。我使用CTE获得了如下字典值列表:例如,对于id:14,父项是13,从父项8->10->12->13->14遍历,其中父项8没有父项id

[
    {
      "id": 14, 
      "name": "cat14", 
      "parent_id": 13, 
      "path_info": [
        8, 
        10, 
        12, 
        13, 
        14
      ]
    }, 
    {
      "id": 15, 
      "name": "cat15", 
      "parent_id": 13, 
      "path_info": [
        8, 
        10, 
        12, 
        13, 
        15
      ]
    }
  ]
我希望将父对象的属性也作为子类别嵌入列表中,如下所示:

{
  "id": 14, 
  "name": "cat14", 
  "parent_id": 13, 
  "subcats": [
       {
         "id: 8", 
         "name": "cat8", 
         "parent_id":null
       }, 
       {
         "id: 10", 
         "name": "cat10", 
         "parent_id":8
       },  
       {
         "id: 12", 
         "name": "cat12", 
         "parent_id":10
       },   
      and similarly for ids 13 and 14..... 
     ]
}, 
{
  "id": 15, 
  "name": "cat15", 
  "parent_id": 13, 
  "subcats": [
       {
         "id: 8", 
         "name": "cat8", 
         "parent_id":null
       }, 
       {
         "id: 10", 
         "name": "cat10", 
         "parent_id":8
       },  
       {
         "id: 12", 
         "name": "cat12", 
         "parent_id":10
       },   
       and similarly for ids 13, 14, 15..... 
     ]
}
]
请注意,“路径信息”已从字典中删除,并且每个id都显示了其详细信息。我想要上面缩进格式的json转储。怎么办?使用flask 0.10、python 2.7,您可以在python代码中执行它:

假设我们有一个json对象。我稍微修改了它-添加了不存在的节点,并按照规范的要求包装成一个对象:

    {
      "array": [
          {
            "id": 14, 
            "name": "cat14", 
            "parent_id": 13, 
            "path_info": [
              8, 
              10, 
              12, 
              13, 
              14
            ]
          }, 
          {
            "id": 15, 
            "name": "cat15", 
            "parent_id": 13, 
            "path_info": [
              8, 
              10, 
              12, 
              13, 
              15
            ]
          },
          {
            "id": 13, 
            "name": "cat13", 
            "parent_id": 12, 
            "path_info": [
              8, 
              10, 
              12, 
              13
            ]
          },
         {
            "id": 12, 
            "name": "cat12", 
            "parent_id": 10, 
            "path_info": [
              8, 
              10, 
              12
            ]
          }, 
          {
            "id": 10, 
            "name": "cat10", 
            "parent_id": 8, 
            "path_info": [
              8, 
              10
            ]
          },
          {
            "id": 8, 
            "name": "cat8", 
            "parent_id": null, 
            "path_info": [
              8
            ]
          }
        ]
    }
然后您可以使用以下代码:

    # load data above from file
    j=json.load(open('json_file_above.json'))   # 

    #  the array with real data we need
    a=j['array']  

    # auxiliary dict which have node identificators as keys and nodes as values
    d={x['id']:x for x in a}  

    # here the magic begins :)
    for x in a:
       # add new key with list to each element
       x['subcats'] = [ 
                       # compose dict element for subcats
                       dict(id=i, name=d[i]['name'], parent_id=d[i]['parent_id'])
                       for 
                       i 
                       in [
                           # we take path_info id list and
                           # cut off the first element - itself
                           y for y in x['path_info'][1:]
                          ]  
                      ]
       del x['path_info']
为了确保您得到了所需的东西:

    >>> print(json.dumps(a, indent=True))
    [
     {
      "name": "cat14",
      "subcats": [
       {
        "name": "cat10",
        "id": 10,
        "parent_id": 8
       },
       {
        "name": "cat12",
        "id": 12,
        "parent_id": 10
       },
       {
        "name": "cat13",
        "id": 13,
        "parent_id": 12
       },
       {
        "name": "cat14",
        "id": 14,
        "parent_id": 13
       }
      ],
      "id": 14,
      "parent_id": 13
     },
     {
      "name": "cat15",
      "subcats": [
       {
        "name": "cat10",
        "id": 10,
        "parent_id": 8
       },
       {
        "name": "cat12",
        "id": 12,
        "parent_id": 10
       },
       {
        "name": "cat13",
        "id": 13,
        "parent_id": 12
       },
       {
        "name": "cat15",
        "id": 15,
        "parent_id": 13
       }
      ],
      "id": 15,
      "parent_id": 13
     },
     {
      "name": "cat13",
      "subcats": [
       {
        "name": "cat10",
        "id": 10,
        "parent_id": 8
       },
       {
        "name": "cat12",
        "id": 12,
        "parent_id": 10
       },
       {
        "name": "cat13",
        "id": 13,
        "parent_id": 12
       }
      ],
      "id": 13,
      "parent_id": 12
     },
     {
      "name": "cat12",
      "subcats": [
       {
        "name": "cat10",
        "id": 10,
        "parent_id": 8
       },
       {
        "name": "cat12",
        "id": 12,
        "parent_id": 10
       }
      ],
      "id": 12,
      "parent_id": 10
     },
     {
      "name": "cat10",
      "subcats": [
       {
        "name": "cat10",
        "id": 10,
        "parent_id": 8
       }
      ],
      "id": 10,
      "parent_id": 8
     },
     {
      "name": "cat8",
      "subcats": [],
      "id": 8,
      "parent_id": null
     }
    ]
    >>>

pythonic代码:简单明了

import json
categories = [] #input
def transform(category, child_node_id):
    category['subcats'].append({
       'id': child_node_id,
       'name': 'cat%s' % child_node_id,
       'parent_id': category['id']
    })


for category in categories:
    category['subcats'] = []
    [transform(category, child_node_id) for child_node_id in category['path_info']]
    category.pop('path_info', None)

print(json.dumps(categories, indent=4))

有一种可以容忍的方法可以通过一些列表/口述理解来做到这一点

lst = [{"id": 14, "name": "cat14", "parent_id": 13, "path_info": [8, 10, 12, 13, 14]}, {"id": 15, "name": "cat15", "parent_id": 13, "path_info": [8, 10, 12, 13, 15]}]

master_dct = { d['id'] : d for d in lst}
for d in lst:
    d['subcats'] = [{field : master_dct[i][field] for field in ['id', 'name', 'parent_id']} \
        for i in d['path_info'] if i in master_dct]

import json
with open('out.json', 'w') as f:
    json.dump(lst, f)