递归函数仅返回嵌套字典的一个分支的结果

时间:2019-04-24 20:14:56

标签: python

我有一个分支嵌套的字典来可视化物种分类数据。我正在尝试编写一个函数,该函数为我提供特定级别的所有分支。

我已经尝试了迭代和递归函数,但是我只使用递归函数。 但是,根据我放置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,因此我无法为以后的应用程序存储该信息

3 个答案:

答案 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()]

请注意,这将返回一个深度嵌套的列表。拼合留给读者练习。