我以平面方式表示类别层次结构 类别层次结构是
category1
category4
category6
category5
category7
category2
category3
我使用字典
将其存储为列表d = [{'id': 1, 'name': 'category1', 'parent_category_id': None, 'level': 1},
{'id': 2, 'name': 'category2', 'parent_category_id': None, 'level': 1},
{'id': 3, 'name': 'category3', 'parent_category_id': None, 'level': 1},
{'id': 4, 'name': 'category4', 'parent_category_id': 1, 'level': 2},
{'id': 5, 'name': 'category5', 'parent_category_id': 1, 'level': 2},
{'id': 7, 'name': 'category6', 'parent_category_id': 4, 'level': 3},
{'id': 7, 'name': 'category7', 'parent_category_id': 5, 'level': 3}]
将此类别列表转换为分层列表(如
)的最佳方法是什么[{'name': 'category1',
'subcategory': [{'name': 'category4',
'subcategory': [{'name': 'category6', 'subcategory': []}]},
{'name': 'category5',
'subcategory': [{'name': 'category7', 'subcategory': []}]}]},
{'name': 'category2', 'subcategory': []},
{'name': 'category3', 'subcategory': []}]
答案 0 :(得分:1)
def flat_to_hierarchical(d, category_id=None):
out = list()
for item in filter(lambda item: item['parent_category_id']==category_id, d):
out.append(dict(
name = item['name'],
subcategories = flat_to_hierarchical(d, item['id'])
))
return out
print(flat_to_hierarchical(d))
答案 1 :(得分:1)
我们从[{1}}开始,给出make_tree
和index
节点标识
root
现在我们需要一种方法来def make_tree (index, root):
if not root in index:
return []
else:
return [ make_node (index, child) for child in index[root] ]
- 这是我们将输入数据中的元素转换为输出树元素的方法
make_node
当然,我们需要根据您的输入数据找到def make_node (index, child):
return \
{ 'name': child['name']
, 'children': make_tree (index, child['id'])
}
的方法。我们使用itertools groupby
,以便我们可以有效地查找所有子节点
make_index
最后,我们写from itertools import groupby
def make_index (nodes):
return \
{ k: list (v)
for (k,v) in
groupby (nodes, lambda n: n['parent_category_id']) }
将所有内容联系起来。请注意,每次迭代都不会重新索引或过滤数据
main
完整的程序演示
def main (nodes, root = None):
return make_tree (make_index (nodes), root)
节目输出
from itertools import groupby
def make_tree (index, root):
if not root in index:
return []
else:
return [ make_node (index, child) for child in index[root] ]
def make_node (index, child):
return \
{ 'name': child['name']
, 'children': make_tree (index, child['id'])
}
def make_index (nodes):
return \
{ k: list (v)
for (k,v) in
groupby (nodes, lambda n: n['parent_category_id']) }
def main (nodes, root = None):
return make_tree (make_index (nodes), root)
d = \
[ {'id': 1, 'name': 'category1', 'parent_category_id': None, 'level': 1}
, {'id': 2, 'name': 'category2', 'parent_category_id': None, 'level': 1}
, {'id': 3, 'name': 'category3', 'parent_category_id': None, 'level': 1}
, {'id': 4, 'name': 'category4', 'parent_category_id': 1, 'level': 2}
, {'id': 5, 'name': 'category5', 'parent_category_id': 1, 'level': 2}
, {'id': 7, 'name': 'category6', 'parent_category_id': 4, 'level': 3}
, {'id': 7, 'name': 'category7', 'parent_category_id': 5, 'level': 3}
]
# get sub-tree of [None] from dataset [d]
print (main (d, None))
答案 2 :(得分:0)
您的问题与我在Calculating the Path from Parent Child Relationships
处回答的问题非常相似我注意到您的数据结构中似乎有很多多余的字段。基本上,您可以通过以下方式表示帖子中的信息:
d = {1: {4: {6: None}, 5: {7: None}}, 2: None, 3: None}
为您重新编写代码。
ds = [{'id': 1, 'name': 'category1', 'parent_category_id': None, 'level': 1},
{'id': 2, 'name': 'category2', 'parent_category_id': None, 'level': 1},
{'id': 3, 'name': 'category3', 'parent_category_id': None, 'level': 1},
{'id': 4, 'name': 'category4', 'parent_category_id': 1, 'level': 2},
{'id': 5, 'name': 'category5', 'parent_category_id': 1, 'level': 2},
{'id': 6, 'name': 'category6', 'parent_category_id': 4, 'level': 3},
{'id': 7, 'name': 'category7', 'parent_category_id': 5, 'level': 3}]
e = {1: {4: {6: None}, 5: {7: None}}, 2: None, 3: None}
parents = set()
children = {}
for d in ds:
c = str(d['id'])
p = str(d['parent_category_id'])
if p is not None:
parents.add(p)
children[c] = p
# recursively determine parents until child has no parent
def ancestors(p):
return (ancestors(children[p]) if p in children else []) + [p]
# for each child that has no children print the geneology
for k in (set(children.keys()) - parents):
print ' '.join(ancestors(k)[1:])
输出:
3
2
1 5 7
1 4 6
要将其转换为嵌套字典,我建议你What is the best way to implement nested dictionaries?