階層辞書にツリーリストの変換
-
09-09-2019 - |
質問
親、レベル、is_leaf_node、is_root_node、is_child_node :。
私はattrsを持つ要素のリストを持っています
私は、階層の辞書には、このリストを変換したいです。 出力辞書の例:
{
'Technology':
{
'Gadgets':{},
'Gaming':{},
'Programming':
{
'Python':{},
'PHP':{},
'Ruby':{},
'C++':{}
},
'Enterprise':{},
'Mac':{},
'Mobile':{},
'Seo':{},
'Ui':{},
'Virtual Worlds':{},
'Windows':{},
},
'News':{
'Blogging':{},
'Economics':{},
'Journalism':{},
'Politics':{},
'News':{}
},}
私は、アルゴリズムを知りません。どうやるか?
解決
ここで説明します。chmod 700のようにそれほど洗練された、再帰バージョンです。もちろん、完全にテストされていない:
def build_tree(nodes):
# create empty tree to fill
tree = {}
# fill in tree starting with roots (those with no parent)
build_tree_recursive(tree, None, nodes)
return tree
def build_tree_recursive(tree, parent, nodes):
# find children
children = [n for n in nodes if n.parent == parent]
# build a subtree for each child
for child in children:
# start new subtree
tree[child.name] = {}
# call recursively to build a subtree for current node
build_tree_recursive(tree[child.name], child, nodes)
他のヒント
親のないすべてはあなたのトップレベルであるので、まずそれらのdictsを作ります。そして、そのトップレベルなどで親を持つすべてのものを見つけるためにあなたの配列を介して第2のパスを行う...それはループや再帰関数のように書くことができます。あなたは本当に「親」以外に提供情報のいずれかを必要としません。
あなたは基本的にやりたいと思っているものはトポロジカル整列の変種であるように、
これは聞こえるする
。このための最も一般的なアルゴリズムは、ソース除去アルゴリズムです。擬似コードは次のようになります:import copy
def TopSort(elems): #elems is an unsorted list of elements.
unsorted = set(elems)
output_dict = {}
for item in elems:
if item.is_root():
output_dict[item.name] = {}
unsorted.remove(item)
FindChildren(unsorted, item.name, output_dict[item.name])
return output_dict
def FindChildren(unsorted, name, curr_dict):
for item in unsorted:
if item.parent == name:
curr_dict[item.name] = {}
#NOTE: the next line won't work in Python. You
#can't modify a set while iterating over it.
unsorted.remove(item)
FindChildren(unsorted, item.name, curr_dict[item.name])
これは明らかに(少なくとも実際のPythonコードのような)場所のカップルに破壊されます。しかし、の、できればのあなたのアルゴリズムがどのように機能するかのアイデアを与えるだろうという。あなたが持っているアイテム(アイテムbは親として項目aを有している、項目AがBの親としてのアイテムを持っていると言う)でのサイクルがあるかどうこれは恐ろしく失敗することに注意してください。しかし、その後、それはおそらくあなたがとにかくやりたいと思っていた形式で表現することは不可能であろう。
このような何かをシンプルに動作します。
def build_tree(category_data):
top_level_map = {}
cat_map = {}
for cat_name, parent, depth in cat_data:
cat_map.setdefault(parent, {})
cat_map.setdefault(cat_name, {})
cat_map[parent][cat_name] = cat_map[cat_name]
if depth == 0:
top_level_map[cat_name] = cat_map[cat_name]
return top_level_map
これを行うには素敵な再帰的な方法:
def build_tree(elems):
elem_with_children = {}
def _build_children_sub_tree(parent):
cur_dict = {
'id': parent,
# put whatever attributes here
}
if parent in elem_with_children.keys():
cur_dict["children"] = [_build_children_sub_tree(cid) for cid in elem_with_children[parent]]
return cur_dict
for item in elems:
cid = item['id']
pid = item['parent']
elem_with_children.setdefault(pid, []).append(cid)
res = _build_children_sub_tree(-1) # -1 is your root
return res
所属していません StackOverflow