我有一个分支嵌套的字典来可视化物种分类数据。我正在尝试编写一个函数,该函数为我提供特定级别的所有分支。
我已经尝试了迭代和递归函数,但是我只使用递归函数。
但是,根据我放置return
/ print
语句的位置,我的函数要么返回None
(但打印正确的信息),要么仅返回数据的一个分支。
使用第二个选项,输出是完美的,直到数据集分支为止。
tree = {"k-b":
{"p-a":
{"c-a":{"o-a":{}, "o-b":{}},
"c-b":{"o-a":{}}},
"p-b":
{"c-a":{"o-a":{},"o-b":{}}}}}
def branches(tree, level):
if level == 0:
#print(tree.keys())
return tree.keys()
else:
for i in tree.keys():
return branches(tree[i], level-1)
print(branchNumber(tree, 2))
对于第2级,我期望[['c-a', 'c-b'], ['c-a']]
(它不一定是数组的数组,并且我不在乎它是否具有dict_keys()或它周围的其他任何东西)
我实际上得到了dict_keys(['c-a', 'c-b'])
,其中不包括第二个分支
或者,如果我在递归调用分支之前删除了“ return”,并取消注释了print语句,则会打印:
dict_keys(['c-a', 'c-b'])
dict_keys(['c-a'])
这正是我想要的输出,但是该函数返回None
,因此我无法为以后的应用程序存储该信息
答案 0 :(得分:2)
您的代码总是返回循环中的第一项,因此您的算法过早结束,并且不会探索所有必要的分支。您可以yield
的结果来创建一个生成器函数(以及其他方法):
tree = {"k-b":
{"p-a":
{"c-a":{"o-a":{}, "o-b":{}},
"c-b":{"o-a":{}}},
"p-b":
{"c-a":{"o-a":{},"o-b":{}}}}}
def branches(tree, level):
if level == 0:
yield list(tree.keys())
elif level > 0:
for v in tree.values():
yield from branches(v, level - 1)
for i in range(4):
print(f"level {i}:", list(branches(tree, i)))
输出:
level 0: [['k-b']]
level 1: [['p-a', 'p-b']]
level 2: [['c-a', 'c-b'], ['c-a']]
level 3: [['o-a', 'o-b'], ['o-a'], ['o-a', 'o-b']]
elif level > 0:
行是一种优化,可避免不必要地深入树中。
另外,for i in tree.keys()
,然后tree[i]
可以更清楚地访问for v in tree.values()
。
答案 1 :(得分:1)
您可能要返回该级别所有项目的列表:
tree = {"k-b":
{"p-a":
{"c-a":{"o-a":{}, "o-b":{}},
"c-b":{"o-a":{}}},
"p-b":
{"c-a":{"o-a":{},"o-b":{}}}}}
def branches(tree, level):
if level == 0:
#print(tree.keys())
return tree.keys()
else:
return [branches(tree[i], level-1) for i in tree.keys()]
print(branches(tree, 2))
输出:
[[dict_keys(['c-a', 'c-b']), dict_keys(['c-a'])]]
答案 2 :(得分:0)
听起来您想返回所有分支的列表。一种方法是使用列表理解:
def branches(tree, level):
if level == 0:
#print(tree.keys())
return tree.keys()
else:
return [branches(tree[i], level-1) for i in tree.keys()]
请注意,这将返回一个深度嵌套的列表。拼合留给读者练习。