我一直在尝试在Python中实现一个简单的树结构。树从具有子节点的单个“根”节点开始,其每个子节点可能有自己的孩子等等。
现在,我想打印树的所有节点的名称,即我想将其转换为列表。我试图使用递归,但遗憾的是,递归返回生成器对象的子树,我无法将其转换为节点。
有人可以帮助我,并指出我在这里做错了吗?
class Node:
def __init__(self,name):
self.name = name
self.children = []
self.parent = None
def appendChild(self,child):
self.children.append(child)
if child is not None:
child.parent = self
def listChildren(self):
yield self
for child in self.children:
yield child.listChildren()
raise StopIteration
# test
r = Node("root")
n = Node("name")
r.appendChild(n)
n.appendChild(Node("name2"))
n.appendChild(Node("name3"))
c = Node("child")
n.appendChild(c)
c.appendChild(Node("child2"))
c.appendChild(Node("child3"))
r.appendChild(Node("name4"))
r.appendChild(Node("name5"))
r.appendChild(Node("name6"))
for child in r.listChildren():
print child.name
输出:
Traceback (most recent call last):
File "C:/Users/User/Documents/TreeNode.py", line 40, in <module>
print child.name
AttributeError: 'generator' object has no attribute 'name'
生成器应该在迭代时被调用,但在我的情况下,r.listChildren()中的每个子进程都是生成器对象。如果这是一个设计缺陷,那么我将不得不寻找另一种生成节点名称列表的方法。
提前谢谢!
答案 0 :(得分:3)
child.listChildren()
将返回生成器对象,而不是实际的子对象。所以你可能想做类似的事情:
def listChildren(self):
yield self
for child in self.children:
for c in child.listChildren():
yield c
raise StopIteration # PS: you don't need to do that explicitly
或者,如果你使用Python 3.3,你可以这样做:
def listChildren(self):
yield self
for child in self.children:
yield from child.listChildren()