I think this might be more useful for you if I post a working example of how to do this, rather than going through where you have code problems. We could have a thorough understanding of this. Your code has the right idea that it should track the depth as it arrives. But the only thing that is missing is the feeling of nested depth (tree). He knows only the previous node_count
, and then its current counter.
My example uses closure to run a depth tracking object, and then creates an internal function for the recursive part.
def recurse(box): boxes = not isinstance(box, (list, tuple)) and [box] or box depth = [1] def wrapped(box): depthStr = '.'.join([str(i) for i in depth]) print "%s %s" % (depthStr, box.name) depth.append(1) for child in box.boxItems: wrapped(child) depth[-1] += 1 depth.pop() for box in boxes: wrapped(box) depth[0] += 1
Example output from your examples:
>>> recurse(example) 1 Example Box 1.1 Big Box 1.1.1 Normal Box 1.1.2 Friendly Box 1.2 Cool Box >>> recurse([example, example]) 1 Example Box 1.1 Big Box 1.1.1 Normal Box 1.1.2 Friendly Box 1.2 Cool Box 2 Example Box 2.1 Big Box 2.1.1 Normal Box 2.1.2 Friendly Box 2.2 Cool Box
Violation of this:
First, we take the box argument and automatically convert it locally to a list if you only passed it in one field. Thus, you can pass either a single box object or a list / tuple of them.
depth
is our depth tracker. Its a list of ints, which we will grow and contract as we recurs. It starts with 1 for the first item / first level. Over time, it may look like this: [1,1,2,3,1]
depending on how deep it goes. This is the main difference between my code and yours . Each recursion has access to this state.
Now we have this internal wrapped
function. He is going to take the current item and print it, and then iterate over his children. We get our print string by entering the current depth list and then the name.
Each time we drop into a child list, we add an initial level of 1 to our depth list, and when we exit this child cycle, we return it again. For each child in this loop, we increment this last element up.
Outside of this internal wrapped
function, we start all this by sorting through our initial fields, calling wrapped
, and then increasing our first level.
The inner wrapped function uses a list of depths in closure. I bet that others can offer some additional improvements in this, but this is what I came up with as an example.
A note about function arguments
We could also design a recurse
instead of a list of variables of variable length instead of checking a list. It will look like this (and get rid of this first check boxes =
):
def recurse(*boxes):
And if you initially started with a list of elements, you can pass it by doing:
>>> boxes = [example, example, example] >>> recurse(*example)