在Python中将父子关系转换为JSON

2 投票
2 回答
2588 浏览
提问于 2025-04-17 02:53

我有一个类似下面的列表。第一列是父节点,第二列是子节点,第三列是节点的属性。我需要把下面的内容转换成像下面这样的JSON格式。

0 0 "flair" 1000
0 1 "analytics" 1000

1 2 "cluster" 1000
2 3 "AgglomerativeCluster" 1000
2 4 "CommunityStructure" 1000

1 5 "Graph" 1000
5 6 "BetweennessCentrality" 1000
5 7 "LinkDistance"

pc = []
pc.append([0, 0 ,"flair", 1000])
pc.append([0,1, "analytics", 1000])
pc.append([1, 2, "cluster", 1000])
pc.append([2 ,3, "AgglomerativeCluster", 1000])
pc.append([2 ,4, "CommunityStructure" ,1000])
pc.append([1 ,5, "Graph", 1000])
pc.append([5, 6, "BetweennessCentrality", 1000])
pc.append([5, 7, "LinkDistance",1000])

{
 "name": "flare",
 "children": [
  {
   "name": "analytics",
   "children": [
    {
     "name": "cluster",
     "children": [
      {"name": "AgglomerativeCluster", "size": 3938},
      {"name": "CommunityStructure", "size": 3812},
     ]
    },
    {
     "name": "graph",
     "children": [
      {"name": "BetweennessCentrality", "size": 3534},
      {"name": "LinkDistance", "size": 5731}
     ]
    }
   ]
  }
 ]
}

2 个回答

1

我不太确定这些'size'属性是从哪里来的,它们在'pc'列表中并没有出现。不过假设它们是从每个列表的第4个项目中取的,并且在输出树中它们应该都是1000,那么这样做应该是可行的。

def make_tree(pc_list):
    results = {}
    for record in pc_list:
        parent_id = record[0]
        id = record[1]

        if id in results:
            node = results[id]
        else:
            node = results[id] = {}

        node['name'] = record[2]
        node['size'] = record[3]
        if parent_id != id:
            if parent_id in results:
                parent = results[parent_id]
            else:
                parent = results[parent_id] = {}
            if 'children' in parent:                
                parent['children'].append(node)
            else:
                parent['children'] = [node]        

    # assuming we wanted node id #0 as the top of the tree          
    return results[0]  

我用make_tree(pc)生成的输出进行美化打印,得到的是:

{'children': [{'children': [{'children': [{'name': 'AgglomerativeCluster',
                                           'size': 1000},
                                          {'name': 'CommunityStructure',
                                           'size': 1000}],
                             'name': 'cluster',
                             'size': 1000},
                            {'children': [{'name': 'BetweennessCentrality',
                                           'size': 1000},
                                          {'name': 'LinkDistance',
                                           'size': 1000}],
                             'name': 'Graph',
                             'size': 1000}],
               'name': 'analytics',
               'size': 1000}],
 'name': 'flair',
 'size': 1000}

虽然键的显示顺序不同,但几乎和你的示例输出一样(只是大小值不同)。

3

对于你的输入,稍微做个小改动。如果根节点是“flair”,我会用‘-1’作为它的父节点ID,而不是用‘0’。

import json
pc = []
pc.append([-1, 0 ,"flair", 1000])
pc.append([0,1, "analytics", 1000])
pc.append([1, 2, "cluster", 1000])
pc.append([2 ,3, "AgglomerativeCluster", 1000])
pc.append([2 ,4, "CommunityStructure" ,1000])
pc.append([1 ,5, "Graph", 1000])
pc.append([5, 6, "BetweennessCentrality", 1000])
pc.append([5, 7, "LinkDistance",1000])

def listToDict(input):
    root = {}
    lookup = {}
    for parent_id, id, name, attr in input:
        if parent_id == -1: 
            root['name'] = name;
            lookup[id] = root
        else:
            node = {'name': name}
            lookup[parent_id].setdefault('children', []).append(node)
            lookup[id] = node
    return root

result = listToDict(pc)
print result
print json.dumps(result)

撰写回答