我有一个类似于以下内容的词典列表:
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个级别的孩子
答案 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'}]