gpt4 book ai didi

Python递归通过对象和子对象,打印子深度数

转载 作者:太空狗 更新时间:2023-10-29 21:35:18 25 4
gpt4 key购买 nike

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

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

最佳答案

我认为如果我发布一个工作示例来说明如何执行此操作可能对您更有帮助,而不是查看您的代码出现问题的地方。这样我们可能会更快地达到理解的程度。您的代码有正确的想法,它需要跟踪深度。但它唯一缺少的是嵌套深度(树)的感觉。它只知道之前的 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 添加到我们的深度列表中,当我们从该子循环中出来时,我们会再次将其弹出。对于该循环中的每个 child ,我们将最后一项递增。

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

关于Python递归通过对象和子对象,打印子深度数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9984513/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com