2016-10-16 12 views
1

私はPythonで書かれた自己ツリーのクラスに問題があります。ツリー内のインスタンスを反復処理する方法はありますか?

class Tree: 
    def __init__(self, parent=0, value=0): 
     self.value = value 
     self.parent = parent 
    def __iter__(self): return self 
    def next(self): 
     tmp = self.value 
     try: 
      self.parent = self.parent.parent 
      self.value = self.parent.value 
     except AttributeError: 
      raise StopIteration 
     return tmp 
    def sum(self): 
     list_ = [item for item in self] 
     print list_ 
     return sum(list_) 

は実際には、「木」は、完全に書かれていますが、現在の問題のブロックをさらに進展されていません。 構造体には2つのインスタンス変数(value,parent)しかありません。 イテレータを使って、現在のインスタンスから最初の親に値を合計したいと思います(すべてが可能な場合)。そのためにsumメソッドが使用されています(追加の変数は不要ですが、さらに問題の説明に役立ちます)。

テストケース

parent = Tree() 
child = Tree(parent=parent, value=8) 
child2 = Tree(parent=child,value=10) 
print child2.sum() 

を実行しているとき、私は、次を得る:

[10] 
10 

してください、それは[10,8]のようになりますけれども、値のリストが一つだけ番号が含まれている理由は、誰もが説明できますか?問題が実装のiternextにあるようだが、私は解決策を修復する方法を理解できません。

ありがとうございます。ここで

+0

項目しか自己を返します。反復は、ルートノードでのみ発生するNoneになるまでself.parentに従う必要があります。これを行うには、おそらくyieldが必要です。また、__init__の定義におけるparentとvalueのデフォルト値は、Noneをデフォルト値として使用しなくてはなりません(MUST)。また、ツリーを構築していない、これは親によってリンクされた項目のリストです。ツリーを適切に実装するには、各ノードにchild1/child2(またはleft/right)インスタンス変数を含めてはいけないので、構造体をルートからそれに向かってナビゲートすることができますか? – barny

+0

へ@barnyへ:私はあなたに、主な親としての「None」について完全に同意します。木にも子どもが入るはずですが、私の場合はたくさんあります。私が書いたように、イテレータの問題のためにこの機能は実装されていません。最後に、self.parentを反復することは良い考えですが、私はそれを良い方法で実装できませんでした。 'next'がself.parentを返す場合(' self = self.parent'であっても)、 'sum'は予想外のループになります。 'yield'を使って実装を表示する場合。それは多くの助けになる可能性があります。 –

答えて

0

私はこのことをTreeと呼ぶことはできません。親ノードと複数のリーフノードが必要であり、単なるオブジェクトの線形接続ではありません。

を参照してください:あなたはLinkedListのを実装したい場合は、別のノートでA general tree implementation?

は、Barnyによってあなたの質問にコメントして作られた提案を検討すべきであると同様に、あなたが目を与えることができます:Python Linked List

現在の実装では、現在の子ノードから先頭の親ノードまで歩くために何らかのループが必要です。次の親属性が見つからない場合は、反復を停止します。

class Tree: 
    def __init__(self, parent=None, value=0): 
     self.value = value 
     self.parent = parent 

    def __iter__(self): 
     _parent = self.parent 
     yield self.value 
     while True: 
      try:    
       yield _parent.value 
       _parent = _parent.parent 
      except AttributeError: 
       break 

    def sum_from_node(self): 
     list_ = [item for item in self] 
     print list_ 
     return sum(list_) 

デモ::以下は今ジェネレータ関数であるクラスの__iter__方法でロジックを置く自己のアイテムのために

parent = Tree() 
child = Tree(parent=parent, value=8) 
child2 = Tree(parent=child,value=10) 
child3 = Tree(parent=child2,value=4) 
print child3.sum_from_node() 
# [4, 10, 8, 0] 
# 22 
0

あなたが行く:

class Tree: 
    def __init__(self, parent=None, value=0): 
     self.value = value 
     self.parent = parent 

    def __iter__(self): 
     yield self.value 
     root = self 
     while root.parent is not None: 
      yield root.parent.value 
      root = root.parent 
     raise StopIteration 


    def tree_sum(self): 
     return sum(list(self)) 


parent = Tree() 
child = Tree(parent=parent, value=8) 
child2 = Tree(parent=child,value=10) 

私はNoneにデフォルトparent値を変更しました。

for i in child2: 
    print(i) 

10 
8 
0 # 0 is here because the parent value is 0 by default. 
+0

非常に良い、ありがとう! –

+0

クラスのインスタンスを反復処理するたびに、リストを作成しています。これは、親の数が増えるにつれて望ましくないかもしれない。 –

+0

K、編集された。今すぐ次の値を生成しています。 – Nf4r

関連する問題