tags:

views:

336

answers:

6

Is there a more Pythonic way to put this loop together?:

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

UPDATE: I think this syntax is probably what I'm going to go with:

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

It would be easier to suggest something if I knew what kind of collection api you're working with. In a good api, you could probably do something like

while tree.hasChildren():
    children = tree.getChildren()
    tree = children[0]
gnud
Is there more DRY solution?
Pavel Shved
Don't repeat yourself...Pavel's talking about not repeating the 'children = tree.getChildren()' Which is actually why I asked this question to begin with...
If you don't use the tree variable later, you can merge those two lines in the loop: children = children[0].getChildren()
sdcvvc
Of course he uses the `tree` variable later - `children` is invalid at the end of the loop...
gnud
Oh, that's right.
sdcvvc
gnud, that's a good point (the api thing), but hasChildren isn't in the API... Anyways you got me thinking and I got it down to this:while node.getChildren(): node = node.getChildren()[0]
As long as getChildren() isn't very expensive, that seems like a good solution
gnud
A: 

I think the code you have is fine. If you really wanted to, you could wrap it all up in a try/except:

while True:
    try:    
        tree = tree.getChildren()[0]
    except (IndexError, TypeError):
        break

IndexError will work if getChildren() returns an empty list when there are no children. If it returns False or 0 or None or some other unsubscriptable false-like value, TypeError will handle the exception.

But that's just another way to do it. Again, I don't think the Pythonistas will hunt you down for the code you already have.

Triptych
A: 

Without further testing, I believe this should work:

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

You might also want to override the __getitem__() (the brackets operator) in the Tree class, for further neatification.

try:    while True: tree=tree[0]
except: pass
Ivan Vučica
No `catch` statement in Python.
Triptych
Corrected very soon after I posted :-)
Ivan Vučica
+2  A: 

(My first answer suggested to use iter(tree.getChildren, None) directly, but that won't work as we are not calling the same tree.getChildren function all the time.)

To fix this up I propose a solution using lambda's non-binding of its variables as a possible workaround. I think at this point this solution is not better than any other previously posted:

You can use iter() in it's second sentinel form, using lamda's strange binding:

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

(Here it assumes getChildren() returns None when there are no children, but it has to be replaced with whatever value it returns ([]?).)

iter(function, sentinel) calls function repeatedly until it returns the sentinel value.

kaizer.se
+1  A: 

Do you really only want the first branch? I'm gonna assume you don't and that you want the whole tree. First I'd do this:

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

This will go through the whole tree. Then you can just:

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

Pythonic, simple, clean, and since it uses generators, will not use much memory even for huge trees.

Lennart Regebro
with `return` you must mean `yield`
kaizer.se
Yes, you are correct. Fixed.
Lennart Regebro
A: 

Hi,

I've fetched the list of anchor tags from a web page by crawling now i need to again get of a list of anchor tags for each of these fetched anchor tags and continue this process till nth level in order to create a tree of anchor tags.i wish to know that how this tree structure can be created.This structure should be able to clearly differentiate between root node and child node.

Kindly suggest some help.

Neha

Neha