通过对象和子对象进行Python递归,打印子深度编号

问题描述

我认为,如果我发布一个如何执行此操作的示例,而不是遍历代码存在问题的地方,可能会对您有所帮助。这样,我们可能会更快地了解。您的代码具有正确的想法,即它需要跟踪深度。但是唯一缺少的是嵌套深度(树)的感觉。它只知道前一个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 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

我们首先接受一个框参数,如果您只传递了一个框项目,则将其自动在本地转换为列表。这样,您既可以传递一个框对象,也可以传递它们的列表/元组。

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

解决方法

我有一个简单的类,其属性可以包含相同类的对象列表

class BoxItem:
  def __init__(self,name,**kw):
      self.name = name
      self.boxItems = []
      ... #more attributes here

box1 = BoxItem('Normal Box')
box2 = BoxItem('Friendly Box')
box3 = BoxItem('Cool Box')
box4 = BoxItem('Big Box',[box1,box2]) #contains some children
example = BoxItem('Example Box',[box4,box3]) #contains another level of children

使用“示例”框对象,我想对它可能具有的所有可能的框子项进行深入的操作,并打印出格式如下的对象:

1 Example Box
 1.1 Big Box
  1.1.1 Normal Box
  1.1.2 Friendly Box
 1.2 Cool Box

不需要Tab键,只是想清楚地显示树格式。我能够走动对象本身并打印出其标题,但无法打印出显示父子关系的前数字。(1、1.1、1.2 …)

在此先感谢您的帮助 :)

编辑 这是到目前为止我一直在处理的内容

def print_boxes(box_list):
  node_count = 0
  for box in box_list:
    node_count += 1
    print str(node_count)+' '+box.name #prints out the root box
    recursive_search(box,node_count)

 def recursive_search(box,node_count): #recursive automatically 
  level = 0
  for child in box.boxItems:
    level += 1
    for x in range(len(child.boxItems)):
      print x+1 #this prints out some proper numbers
    print "level: "+str(level) #experiment with level
    print child.name #prints out child box name
    recursive_search(child,node_count) #runs the function again  inside the function

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...