我有一个带有属性的简单类,该属性可以包含同一类的对象列表
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
不需要Tabbing,只是想清楚地显示树格式。我能够自己走下来并打印出他们的标题,但是我无法打印显示父/子关系的前面数字。 (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
答案 0 :(得分:9)
我认为如果我发布一个如何执行此操作的工作示例,而不是通过代码遇到问题的位置,那么对您来说可能会更有帮助。我们可能会以这种方式更快地达到理解的程度。您的代码有正确的想法,它需要跟踪深度。但它唯一缺少的是嵌套深度(树)。它只知道先前的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
打破这种局面:
我们首先接受一个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
答案 1 :(得分:1)
您有两种选择:
myRecursiveFunction(..., ancestry=[])
__init__
构造函数中,为每个子级设置child.parent = self
)。如果你打算在一个以上的盒子里安装一个BoxItem,那就不好了。