2016-04-01 19 views
0

だから、Pythonはこれを本当にしません。私はツリーと呼ばれるクラスを持っています、それはバイナリツリータイプです。参照のクラスのインスタンスを渡すPython

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

    def filler(self, lista, tree): 
     tree = Tree() 
     nr = len(lista) 
     nr //= 2 
     if len(lista) == 0: 
      return 
     if len(lista) == 1: 
      tree.data = lista[0] 
      return 
     tree.data = lista[nr] 
     self.filler(lista[:nr], tree.left) 
     self.filler(lista[nr:], tree.right) 

機能filler()は、リストをバイナリツリーに変換します。

tr = Tree() 
tr2 = Tree() 
l = self.ctrler.Backtrack(self.ctrler.tsk, 0) -- some list 
tr.filler(l, tr2) 
print(tr2.data) 

結果はNoneです。 filler()は何もしません。これについて何かできますか? tr2オブジェクトを参照渡しできますか?私が参照渡しできない場合、リストをバイナリツリーに変換するにはどうすればよいですか?フィラーのツリーのinstatiationなし

トレースバック:

Traceback (most recent call last): 
    File "D:/Projects/Python/AIExcavator/src/ui.py", line 75, in <module> 
    uier.inter() 
    File "D:/Projects/Python/AIExcavator/src/ui.py", line 63, in inter 
    tr.filler(l, tr2) 
    File "D:\Projects\Python\AIExcavator\src\Backtracking.py", line 79, in filler 
    self.filler(lista[:nr], tree.left) 
    File "D:\Projects\Python\AIExcavator\src\Backtracking.py", line 78, in filler 
    tree.data = lista[nr] 
AttributeError: 'NoneType' object has no attribute 'data' 
+0

リストのリストです。私はそこで再帰を使用します。私の再帰は私のリストが終わったときに終わらなければならない。バイナリツリーを埋めるために、私のリストを2、左右に分割しました。それは正常に動作します(毎回、渡されたlsitの長さを印字することによってチェックされます)が、tr2を埋めることはありません – Mocktheduck

答えて

2

fillerは、再帰呼び出しを行うためにはselfしか必要ないため、とにかく少し奇妙です。これは、クラスメソッドを使用することの利点は、あなたがfrom_listを再定義することなく、Treeのサブクラスを定義することができるということです

class Tree(object): 

    def __init__(self, data=None, left=None, right=None): 
     self.left = left 
     self.right = right 
     self.data = data 

    # The former method filler() 
    @classmethod 
    def from_list(cls, lista): 
     if lista: 
      # All non-empty lists are the same. 
      # Specifially, nr = 0 for a single-element list, 
      # and lista[:nr] and lista[nr+1:] are empty lists 
      # in the edge cases. 
      nr = len(lista) // 2 
      return cls(lista[nr], 
         cls.from_list(lista[:nr]), 
         cls.from_list(lista[nr+1:])) 
     else: 
      return None 

tree = Tree.from_list([1,2,3,4,5,6]) 

のように、クラスメソッドとしてそれがより適切なものを作り、本当に別のコンストラクタです。あなたは、各(サブ)ツリーを作成するclsを使用しているため、戻り値は依然として、BackwardsTree、ないTreeのインスタンスになり、関数をオーバーライドし、代わりになかったので、BackwardsTree.from_listTree.from_listに解決が

class BackwardsTree(Tree): 
    def __init__(self, data=None, left=None, right=None): 
     self.data = data 
     # Swap the left and right subtrees 
     self.right = left 
     self.left = right 

bt = BackwardsTree.from_list([1,2,3,4,5,6]) 

を考えてみましょう方法の中にハードコーディングTree

+0

何がありますか? – Mocktheduck

+0

'cls'はクラスが実際にメソッドを呼び出すものです。 'Tree.from_list(...) 'では' Tree'です。 'SomeSubclassOfTree.from_list(...)'では 'SomeSubclassOfTree'です。 – chepner

+0

これは初めてのことです。だから私はクラスをもうコールするのにツリーを必要としませんか? clsを自分で置き換えることはできますか? – Mocktheduck

1

あなたは

tr.filler(l, tr2) 

を書きますが、新しいツリーオブジェクトとそれを消すようフィラーで、あなたは、TR2を使用していません。あなたはtree.lefttree.rightを渡すので、コメントで指摘したようにまた

def filler(self, lista, tree): 
    tree = Tree() 

self.filler(lista[:nr], tree.left) 
self.filler(lista[nr:], tree.right) 

は両方ともNoneながらfillertreeオブジェクト、ないNoneを期待し、間違っています。

については、を参照してください。mutablesについては、Pythonでお読みください。 TL; DR:tr2fillerに渡してfillerに変更すると、実際に変更されます。

+0

私はそれをしないと、treeが値のないのでtree.dataは存在しません。 .. 私は何をすべきか? – Mocktheduck

+0

それは言うべきではありません。完全なコードを投稿して、エラーとその行を表示してください。 –

+0

'fill 'の最後の2行です。新しく作成された' Tree'インスタンスの 'left'と' right'属性を渡します。 'None'です。 –

関連する問題