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