将递归生成器对象转换为列表

时间:2012-11-07 18:01:48

标签: python recursion iterator python-2.7 generator

我一直在尝试在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()中的每个子进程都是生成器对象。如果这是一个设计缺陷,那么我将不得不寻找另一种生成节点名称列表的方法。

提前谢谢!

1 个答案:

答案 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()