2016-05-01 11 views
4

私は非常に単純なツリーのクラスを書いている:Pythonクラスに複数の異なるイテレータを定義できますか?

class Tree: 
    def __init__(self, value_ = None, children_ = None): 
     self.value = value_ 
     self.children = children_ 

私はつまり、単純なループでDFSとBFSの両方トラバーサルを実行できるようにしたいと思います:

t = Tree() 
# ...fill tree... 

for node in t: 
    print(node.value) 

C++では、たとえば、複数のタイプのイテレータを使用することができます。そのため、DFSとBFSイテレータの両方を定義し、実行したいトラバースのタイプに応じてどちらか一方を使用できます。これはPythonで可能ですか?

+0

'Tree'はクラスではありません。それは関数です。クラスは以下のように定義されています: 'class Tree(object):' – ozgur

+0

@ozgur:Typo - キャッチしてくれてありがとう! – tonysdg

+0

特定のケースで実行するイテレーションのタイプをどのように指定しますか? – BrenBarn

答えて

6

:あなたは、その後のようなものを書くでしょう。

from collections import deque 

class Tree(object): 
    def __init__(self, value): 
     self.value = value 
     self.left = None 
     self.right = None 

    def __iter__(self): 
     if self.left: 
      for x in self.left: 
       yield x 

     yield self.value 

     if self.right: 
      for x in self.right: 
       yield x 

    def bfs(self): 
     q = deque([self]) 
     while q: 
      x = q.popleft() 
      if x: 
       yield x.value 
       q.extend([x.left, x.right]) 

使い方のショート例:以下は、「デフォルト」イテレータはDFSとどれがさらに別の方法でBFSをサポートしていない単純なバイナリツリーです

root = Tree(2) 
root.left = Tree(1) 
root.right = Tree(4) 
root.right.left = Tree(3) 
root.right.right = Tree(5) 

print list(root) # [1, 2, 3, 4, 5] 
print list(root.bfs()) # [2, 1, 4, 3, 5] 
1

2つのタイプの繰り返しに対して、クラスに別々のメソッドを記述することができます。これらは、たとえば、必要な順序で値を生成するジェネレータです。あなたが複数のメソッドを返すイテレータを持っており、「デフォルト」__iter__として1を持つことができます

for node in t.depth_first(): 
    # ... 

for node in t.breadth_first(): 
    # ... 
関連する問題