2013-07-05 47 views
0

名单我有类型的字典列表看起来是这样的:建筑,父子依赖

list = [{'parent': u'#5963','id': 5962},{'parent': u'','id': 5963}, 
{'parent': u'#5963', 'id': 5964}, {'parent': u'#5966', 'id': 5967}, 
{'parent': u'#5963','id': 5966}, {'parent': u'#5962','id': 5968} ] 

实际类型的字典是一个有点复杂 - 他们有更多的键和值。

正如你所看到的 - 每个字典都有一个“父母”键,它告诉我们元素父母的ID和'ID'键。

现在的问题是:是否有可能建立一个新的列表(或排序这一个)的方式,所有的字母都是父母的方式?

所以新的字典将是:

[{'parent': u'','id': 5963},{'parent': u'#5963','id': 5962}, 
{'parent': u'#5962','id': 5968}, {'parent': u'#5963', 'id': 5964}, 
{'parent': u'#5963','id': 5966}, {'parent': u'#5966', 'id': 5967} ] 

PS:有可能没有根元素
PPS(用“父”键=“”元素):父元素可以具有多于1-2级的儿童

+2

我不明白现在

您可以使用这两个函数进行排序列表。 “亲子方式”是什么意思?或者另一个问题:你想完成什么?我敢肯定,你可以使用树来摆脱这些问题... – tamasgal

+0

由于SQL查询,我得到第一个列表。然后它被传递给一个模板以建立一个表格。模板使用列表元素来创建表格的行。我现在需要的是 - 它以重新排列这个列表的方式,结果表将有一个层次结构,因此是父子方式。 – konart

回答

1

你不能这样做,直接排序,首先从你的列表中建立一棵树。您需要两个信息:顶级节点列表中的树和父母/子女关系(或者没有父母或孩子与不存在的父节点):

def build_tree(l): 
    exists = set(map(lambda x : x['id'], l)) 

    tops = [] 
    children = {} 
    for e in l: 
     parent = e['parent'] 
     if not parent: 
      tops.append(e) 
      continue 

     parent = int(parent[1:]) 
     if parent not in exists: 
      tops.append(e) 
      continue 

     if parent in children: 
      children[parent].append(e) 
     else: 
      children[parent] = [ e ] 

    return children, tops 

然后做树的深度优先遍历用递归函数:

def build_list(children, top): 
    l = [ top ] 
    if top['id'] in children: 
     for child in children[top['id']]: 
      l += build_list(children, child) 
    return l 

第一个功能给你的孩子/关系结构,而第二个让你建立对每个可能的顶部节点列表。如果删除节点5963,这将使

l = [{'parent': u'#5963','id': 5962},{'parent': u'','id': 5963}, 
{'parent': u'#5963', 'id': 5964}, {'parent': u'#5966', 'id': 5967}, 
{'parent': u'#5963','id': 5966}, {'parent': u'#5962','id': 5968} ] 
children, tops = build_tree(l) 
for top in tops: 
    print build_list(children, top) 
# outputs : [{'id': 5963, 'parent': u''}, {'id': 5962, 'parent': u'#5963'}, 
# {'id': 5968, 'parent': u'#5962'}, {'id': 5964, 'parent': u'#5963'}, 
# {'id': 5966, 'parent': u'#5963'}, {'id': 5967, 'parent': u'#5966'}] 

[{'id': 5962, 'parent': u'#5963'}, {'id': 5968, 'parent': u'#5962'}] 
[{'id': 5964, 'parent': u'#5963'}] 
[{'id': 5966, 'parent': u'#5963'}, {'id': 5967, 'parent': u'#5966'}] 
+0

如果没有顶级节点会怎么样? (没有与'父母'键等于''的字典) – konart

+0

@konart我的当前代码在这种情况下失败,但是当没有“父母”时数据看起来像什么?是否因为孩子参考非现有父母?或者你有父/子关系中的循环吗? – Guillaume

+0

假设我们正在谈论一些有票的时间跟踪系统(一张票=一项任务)。每个任务可能有一些子任务。顶级任务可以由一个用户拥有,但是由其他人来分。当顶层任务的所有者请求他拥有的任务时 - 他会得到与我的问题类似的列表,但是当列表仅由拥有子任务的用户请求时,他将看到的列表将相同,顶级任务除外(代码中的顶级节点)。所以所有的字典都会有一些父类,但是不会有单根。 – konart