2010-08-12 76 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