Python 循环 | "do-while" 遍历树结构

2 投票
5 回答
2163 浏览
提问于 2025-04-15 14:45

有没有更符合Python风格的方法来写这个循环呢?

while True:
    children = tree.getChildren()
    if not children:
        break
    tree = children[0]

更新:我觉得这个写法可能是我最终会选择的:

while tree.getChildren():
    tree = tree.getChildren()[0]

5 个回答

1

你真的只想要第一条分支吗?我假设你不是这样想的,而是想要整个树的内容。首先,我会这样做:

def allitems(tree):
    for child in tree.getChildren():
        yield child
        for grandchild in allitems(child):
            yield grandchild

这样做会遍历整个树。然后你可以直接:

for item in allitems(tree):
    do_whatever_you_want(item)

这种写法在Python中很常见,简单明了,而且因为它使用了生成器,所以即使是很大的树也不会占用太多内存。

2

我之前的回答建议直接使用 iter(tree.getChildren, None),但这样做不行,因为我们并不是一直在调用同一个 tree.getChildren 函数。

为了解决这个问题,我提出了一个使用 lambda 的变量不绑定特性的解决方案,作为一种可能的变通办法。不过我觉得这个方案并没有比之前其他的方案更好:

你可以使用 iter() 的第二种哨兵形式,利用 lambda 的奇怪绑定:

for children in iter((lambda : tree.getChildren()), None):
    tree = children[0]

(这里假设 getChildren() 在没有子节点时返回 None,但你需要用它实际返回的值来替换这个 None(比如 []?)。)

iter(function, sentinel) 会重复调用这个函数,直到它返回哨兵值为止。

4
children = tree.getChildren()
while children:
    tree = children[0]
    children = tree.getChildren()

如果我知道你正在使用什么样的集合接口,那我就能更容易地给你建议。在一个好的接口中,你可能可以这样做

while tree.hasChildren():
    children = tree.getChildren()
    tree = children[0]

撰写回答