Python循环|在树上做“做什么”

时间:2009-10-02 19:57:51

标签: python

是否有更多的Pythonic方法将这个循环放在一起?:

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

更新: 我认为这种语法可能就是我要用的内容:

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

5 个答案:

答案 0 :(得分:4)

children = tree.getChildren()
while children:
    tree = children[0]
    children = tree.getChildren()
如果我知道你正在使用什么样的收集api,那么建议一些东西会更容易。在一个好的api中,你可能会做类似

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

答案 1 :(得分:2)

(我的第一个回答建议直接使用iter(tree.getChildren, None),但这不起作用,因为我们没有一直调用相同的tree.getChildren函数。)

为了解决这个问题,我提出了一个解决方案,使用lambda的非变量绑定作为一种可能的解决方法。我认为此时此解决方案并不比之前发布的其他解决方案更好:

您可以使用lamda奇怪的绑定在其第二个哨兵表格中使用iter()

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

(这里假设getChildren()在没有子节点时返回None,但必须用它返回的任何值替换它([]。)。)

iter(function, sentinel)重复调用函数,直到它返回sentinel值。

答案 2 :(得分: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)

Pythonic,简单,干净,并且因为它使用生成器,即使对于大树也不会使用太多内存。

答案 3 :(得分:0)

我认为你的代码很好。如果你真的想要,你可以在try / except中包装它们:

while True:
    try:    
        tree = tree.getChildren()[0]
    except (IndexError, TypeError):
        break
如果IndexError在没有子项时返回空列表,则

getChildren()将起作用。如果它返回False0None或其他一些不可取消订阅的类似虚假的值,TypeError将处理该异常。

但这只是另一种方式。同样,我认为Pythonistas不会因为你已有的代码而找不到你。

答案 4 :(得分:0)

如果没有进一步测试,我相信这应该有效:

try:    while True: tree=tree.getChildren()[0]
except: pass

您可能还想覆盖__getitem__()类中的Tree(括号运算符),以进一步澄清。

try:    while True: tree=tree[0]
except: pass