构建具有父子依赖关系的列表

时间:2013-07-05 08:50:15

标签: python parent-child

我有一个类似于以下内容的词典列表:

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} ]

实际的dicts有点复杂 - 它们有更多的键和值。

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

现在的问题是:是否有可能以所有dicts以父子方式放置的方式构建新列表(或对此列表进行排序)?

所以新的词典将是:

[{'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:可能没有根元素(带有'parent'key =''的元素)
PPS:父元素可能有超过1-2个级别的孩子

1 个答案:

答案 0 :(得分: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

第一个函数为您提供子/关系结构,第二个函数允许您为每个可能的顶级节点构建一个列表。

现在,您可以使用这两个功能对列表进行排序:

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'}]

如果删除节点5963,则会给出:

[{'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'}]