3

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() のすべての子はジェネレーター オブジェクトです。これが設計上の欠陥である場合、ノード名のリストを生成する別の方法を探す必要があります。

前もって感謝します!

4

1 に答える 1

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()
于 2012-11-07T18:13:09.830 に答える