2010-08-12 78 views
1

我有表,看起来像这样:试图拿出一个递归函数来展开树在Python

id | parentid | name 
--------------------- 
1 | 0  | parent1 
--------------------- 
2 | 0  | parent2 
--------------------- 
3 | 1  | child1 
--------------------- 
4 | 3  | subchild1 

现在我试图拿出一个有效的方式来采取数据库中的数据和创建一个Python字典。

基本上,我希望能够做到:

tree = expand(Session.query(mytable).all()) 
print tree['parent2']['child2'] 

# result would be 'subchild1' 

我在与如何做到这一点完全丧失......我一直在用下面的函数乱搞,但我可以”让它工作。任何帮助,将不胜感激。

def expand(tree): 

    parents = [i for i in tree if i.parentid == 0] 

    for parent in parents: 
     children = expand(parent) 
+0

它没有解决你的Python问题,但你可能会发现这个有趣的:http://dev.mysql.com/tech-resources/articles/hierarchical-data.html。 – FMc 2010-08-12 13:20:11

回答

1

如果我理解正确,那么其父ID为0的项目是根号还是第一级?

如果是这样,你的方法应该是这样的:

def expand(tree, id): 
    expanded_tree = {} 

    parents = [i for i in tree if i.parentid == id] 

    for parent in parents: 
     expanded_tree[parent.name] = expand(tree, parent.id) 

    return expanded_tree 

,你会开始它像:

tree = expand(Session.query(mytable).all(), 0) 
+0

我刚刚修复了递归的代码。要么它错过了函数的结尾,或者他有一个错误,但是是这样的,因为没有返回语句。 – 2010-08-12 13:34:15

+0

你会如何返回树?在递归函数中返回数据完全落在我的头上 – dave 2010-08-12 13:34:39

+0

完成的函数向您展示如何通过递归完成,虽然THC4k是正确的,但递归并不是解决此问题的最佳解决方案。 – 2010-08-14 18:11:24

1

您的例子不匹配的数据给出,但这个应该是你想。

它不是递归的,因为递归在这里没有意义:输入数据没有递归结构(这就是我们正在创建的),所以你可以写成递归的循环...这是一个漂亮的毫无意义的事情要做的Python。

data = [ (1,0,"parent1"), (2,0,"parent2"), (3,1,"child1"), (4,3,"child2")] 

# first, you have to sort this by the parentid 
# this way the parents are added before their children 
data.sort(key=lambda x: x[1]) 

def make_tree(data): 
    treemap = {} # for each id, give the branch to append to 
    trees = {} 
    for id,parent,name in data: 
     # {} is always a new branch 
     if parent == 0: # roots 
      # root elements are added directly 
      trees[name] = treemap[id] = {} 
     else: 
      # we add to parents by looking them up in `treemap` 
      treemap[parent][name] = treemap[id] = {} 

    return trees 

tree = make_tree(data) 
print tree['parent1']['child1'].keys() ## prints all children: ["child2"] 
+0

+1作为'make_tree'中的第一步,我们可以通过初始化树图来跳过排序步骤吗?例如:'treemap = dict((d [0],{})for d in data)'。 – FMc 2010-08-12 14:14:58

+0

@FM:是的,也可以。但我宁愿要求数据库的排序列表:] – 2010-08-12 15:35:39