python - 字典叶生成器

标签 python dictionary recursion tree

这是我的树,一个嵌套的字典

tree = {"root": {"branch_a": {"branch_aa": 0, "branch_ab": 1},
                 "branch_b": 1,
                 "branch_c": {"branch_ca": {"branch_caa": 0}}}}

我设法写了一个打印所有叶子的函数

def print_leaves(tree):
    if not hasattr(tree, "__iter__"):
        print(tree)
    elif isinstance(tree, dict):
        for branch in tree.values():
            print_leaves(branch)

产生所需的输出

0
1
1
0

在这一点上,我认为将操作(在本例中为打印)与对叶子的访问分离会很好。所以我稍微修改了上面的函数,把它变成了一个生成器,并将打印部分移动到一个for循环中。

def generate_leaves(tree):
    if not hasattr(tree, "__iter__"):
        yield tree
    elif isinstance(tree, dict):
        for branch in tree.values():
            generate_leaves(branch)

for leaf in generate_leaves(tree):
    print(leaf)

...不幸的是,这不起作用。

首先,为什么它不起作用? 然后,当然,如何正确编写叶生成器?

最佳答案

您没有使用递归调用的结果。这适用于没有返回值的 print_leaves,但不适用于具有 returnyield 的函数。

这是长版:

def generate_leaves(tree):
    if not hasattr(tree, "__iter__"):
        yield tree
    elif isinstance(tree, dict):
        for branch in tree.values():
            for leaf in generate_leaves(branch):
                yield leaf

for leaf in generate_leaves(tree):
    print(leaf)

幸运的是,我们可以使用 yield from 使它更短:

def generate_leaves(tree):
    if not hasattr(tree, "__iter__"):
        yield tree
    elif isinstance(tree, dict):
        for branch in tree.values():
            yield from generate_leaves(branch)

for leaf in generate_leaves(tree):
    print(leaf)

请注意,您只需要一个带有一个条件的if/else;不需要带有两个冗余条件的 if/elif:

def generate_leaves(tree):
    if not isinstance(tree, dict):
        yield tree
    else:
        for branch in tree.values():
            yield from generate_leaves(branch)

for leaf in generate_leaves(tree):
    print(leaf)

关于 yield from 的资源:

关于python - 字典叶生成器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70337670/

相关文章:

python - Boost Python Hello World 示例在 Python 中不起作用

python - 在 MATLAB 中创建共享库

python - 查找给定值的所有键

java - 硬件递归分而治之算法

python - 为什么 ElementTree 不删除所有子节点?

python - 为什么 python 允许我实例化这个类?我没有实现抽象方法

ios - 我的 map 隐藏了所有屏幕边界并隐藏了导航栏

android - 我们如何在 Android 应用程序中提供字典服务?

Python顺序遍历到一个平面列表

C++ 递归可变参数 Lambda