我认为,如果我发布一个如何执行此操作的示例,而不是遍历代码存在问题的地方,可能会对您有所帮助。这样,我们可能会更快地了解。您的代码具有正确的想法,即它需要跟踪深度。但是唯一缺少的是嵌套深度(树)的感觉。它只知道前一个
node_count,然后知道它的当前子计数。
我的示例使用闭包启动深度跟踪对象,然后创建一个内部函数来执行递归部分。
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
您的示例的输出示例:
>>> recurse(example)1 Example Box1.1 Big Box1.1.1 Normal Box1.1.2 Friendly Box1.2 Cool Box>>> recurse([example, example])1 Example Box1.1 Big Box1.1.1 Normal Box1.1.2 Friendly Box1.2 Cool Box2 Example Box2.1 Big Box2.1.1 Normal Box2.1.2 Friendly Box2.2 Cool Box
分解如下:
我们首先接受一个框参数,如果您只传递了一个框项目,则将其自动在本地转换为列表。这样,您既可以传递一个框对象,也可以传递它们的列表/元组。
depth是我们的深度跟踪器。它是一个整数列表,随着递归发生,我们将逐步建立和缩小这些整数。对于第一项/第一级,它从1开始。随着时间的流逝,它看起来可能像这样:
[1,1,2,3,1]取决于遍历的深度。
这是我的代码与您的代码之间的主要区别 。每次递归都可以访问此状态。
现在我们有了这个内部
wrapped功能。它将采用当前的盒子项目并打印它,然后遍历其子项目。我们先加入当前深度列表,然后再加入名称,从而获得打印字符串。
每次我们下拉到一个子列表时,都会在深度列表中添加一个起始级别1,当我们退出该子循环时,会再次将其弹出。对于该循环中的每个孩子,我们将最后一项递增。
在该
wrapped内部函数之外,我们然后通过遍历初始框,调用
wrapped然后递增第一级来开始整个操作。
内部包装函数在闭包中使用深度列表。我愿意打赌,其他人可以对此做一些进一步的改进,但是我想出了一个例子。
关于函数的参数的注意事项
我们还可以设计
recurse成采用可变长度的参数列表,而不是检查列表。看起来像这样(并摆脱了第一个
boxes =检查):
def recurse(*boxes): #boxes will always come in as a tuple no matter what>>> recurse(example)>>> recurse(example, example, example)
并且如果您最初是从一列盒子开始的,则可以通过执行以下操作来传递它:
>>> boxes = [example, example, example]>>> recurse(*example) # this will unpack your list into args



