Python 递归构建分层JSON树?
我有一个父子关系数据库。数据如下所示,但可以以任何方式显示(字典、列表列表、JSON等) 我需要的输出是一个层次化的JSON树,它将用d3呈现。数据中有离散的子树,我将把它附加到根节点。所以我需要递归地遍历链接,并建立树结构。我能做的最远的事情就是遍历所有人并附加他们的孩子,但我不知道如何进行更高阶的链接(例如,如何将一个有孩子的人附加到其他人的孩子)。这与另一个问题类似,但我无法提前知道根节点,因此无法实现可接受的解决方案 我将从我的示例数据中获得以下树结构Python 递归构建分层JSON树?,python,django,json,recursion,d3.js,Python,Django,Json,Recursion,D3.js,我有一个父子关系数据库。数据如下所示,但可以以任何方式显示(字典、列表列表、JSON等) 我需要的输出是一个层次化的JSON树,它将用d3呈现。数据中有离散的子树,我将把它附加到根节点。所以我需要递归地遍历链接,并建立树结构。我能做的最远的事情就是遍历所有人并附加他们的孩子,但我不知道如何进行更高阶的链接(例如,如何将一个有孩子的人附加到其他人的孩子)。这与另一个问题类似,但我无法提前知道根节点,因此无法实现可接受的解决方案 我将从我的示例数据中获得以下树结构 { "name":"Root",
{
"name":"Root",
"children":[
{
"name":"Tom",
"children":[
{
"name":"Dick",
"children":[
{"name":"Harry"}
]
},
{
"name":"Larry"}
]
},
{
"name":"Bob",
"children":[
{
"name":"Leroy"
},
{
"name":"Earl"
}
]
}
]
}
这个结构在我的d3布局中呈现为这样 尝试以下代码:
import json
links = (("Tom","Dick"),("Dick","Harry"),("Tom","Larry"),("Tom","Hurbert"),("Tom","Neil"),("Bob","Leroy"),("Bob","Earl"),("Tom","Reginald"))
name_to_node = {}
root = {'name': 'Root', 'children': []}
for parent, child in links:
parent_node = name_to_node.get(parent)
if not parent_node:
name_to_node[parent] = parent_node = {'name': parent}
root['children'].append(parent_node)
name_to_node[child] = child_node = {'name': child}
parent_node.setdefault('children', []).append(child_node)
print json.dumps(root, indent=4)
如果要将数据格式化为HTML/JS本身的层次结构,请查看: 如果您有大量数据,Web转换将更快,因为它使用reduce功能,而Python缺少函数式编程
顺便说一句:我也在研究同一个主题,即在d3.js中生成可折叠的树结构。如果你想一起工作,我的电子邮件是:erprateek。vit@gmail.com.要识别根笔记,您可以解压缩
链接
并查找非孩子的家长:
parents, children = zip(*links)
root_nodes = {x for x in parents if x not in children}
然后可以应用递归方法:
import json
links = [("Tom","Dick"),("Dick","Harry"),("Tom","Larry"),("Bob","Leroy"),("Bob","Earl")]
parents, children = zip(*links)
root_nodes = {x for x in parents if x not in children}
for node in root_nodes:
links.append(('Root', node))
def get_nodes(node):
d = {}
d['name'] = node
children = get_children(node)
if children:
d['children'] = [get_nodes(child) for child in children]
return d
def get_children(node):
return [x[1] for x in links if x[0] == node]
tree = get_nodes('Root')
print json.dumps(tree, indent=4)
我使用了一个集合来获取根节点,但是如果顺序很重要,您可以使用一个列表和。有点麻烦。对于更多的链接,您的代码无法按预期工作:例如,当我尝试使用这些链接时,Tom出现了多次!链接=(“汤姆”、“迪克”)、(“迪克”、“哈里”)、(“汤姆”、“拉里”)、(“汤姆”、“赫伯特”)、(“汤姆”、“尼尔”)、(“鲍勃”、“勒罗伊”)、(“鲍勃”、“厄尔”)、(“汤姆”、“雷金纳德”))
import json
links = [("Tom","Dick"),("Dick","Harry"),("Tom","Larry"),("Bob","Leroy"),("Bob","Earl")]
parents, children = zip(*links)
root_nodes = {x for x in parents if x not in children}
for node in root_nodes:
links.append(('Root', node))
def get_nodes(node):
d = {}
d['name'] = node
children = get_children(node)
if children:
d['children'] = [get_nodes(child) for child in children]
return d
def get_children(node):
return [x[1] for x in links if x[0] == node]
tree = get_nodes('Root')
print json.dumps(tree, indent=4)