web-dev-qa-db-ja.com

self.xxxxをデフォルトのパラメータとして使用する-Python

私は宿題の問題の1つを単純化し、コードを少し改善しようとしています。私が取り組んでいるのは、二分探索木です。現在、Tree()クラスに、すべての要素を検索してリストに入れる関数があります。

_tree = Tree()
#insert a bunch of items into tree
_

次に、makeList()関数を使用してツリーからすべてのノードを取得し、それらをリストに入れます。 makeList()関数を呼び出すには、tree.makeList(tree.root)を実行します。私にはこれは少し繰り返しのようです。私はすでに_tree._でツリーオブジェクトを呼び出しているので、_tree.root_は少し入力するだけの無駄です。

現在、makeList関数は次のとおりです。

_    def makeList(self, aNode):
        if aNode is None:
            return []
        return [aNode.data] + self.makeList(aNode.lChild) + self.makeList(aNode.rChild)
_

ANode入力を_aNode = self.root_(これは機能しません)などのデフォルトのパラメーターにして、tree.makeList()で関数を実行できるようにします。

最初の質問は、なぜそれが機能しないのですか?
2番目の質問は、それが機能する方法はありますか?ご覧のとおり、makeList()関数は再帰的であるため、関数の先頭で何も定義できないか、無限ループになります。

[〜#〜] edit [〜#〜]要求されたすべてのコードは次のとおりです。

_class Node(object):
    def __init__(self, data):
        self.data = data
        self.lChild = None
        self.rChild = None

class Tree(object):
    def __init__(self):
        self.root = None

    def __str__(self):
        current = self.root

    def isEmpty(self):
        if self.root == None:
            return True
        else:
            return False

    def insert (self, item):
        newNode = Node (item)
        current = self.root
        parent = self.root

        if self.root == None:
            self.root = newNode
        else:
            while current != None:
                parent = current
                if item < current.data:
                    current = current.lChild
                else:
                    current = current.rChild

            if item < parent.data:
                parent.lChild = newNode
            else:
                parent.rChild = newNode

    def inOrder(self, aNode):
        if aNode != None:
            self.inOrder(aNode.lChild)
            print aNode.data
            self.inOrder(aNode.rChild)

    def makeList(self, aNode):
        if aNode is None:
            return []
        return [aNode.data] + self.makeList(aNode.lChild) + self.makeList(aNode.rChild)


    def isSimilar(self, n, m):
        nList = self.makeList(n.root)
        mList = self.makeList(m.root) 
        print mList == nList 
_
60
chrisheinze

larsmans answered 最初の質問

2番目の質問については、再帰を回避するために、ジャンプする前に単に確認できますか?

def makeList(self, aNode=None):
    if aNode is None:
        aNode = self.root
    treeaslist = [aNode.data]
    if aNode.lChild:
        treeaslist.extend(self.makeList(aNode.lChild))
    if aNode.rChild:
        treeaslist.extend(self.makeList(aNode.rChild))
    return treeaslist
44
nofinator

デフォルトの引数は呼び出し時ではなく関数定義時に評価されるため、機能しません。

def f(lst = []):
    lst.append(1)
    return lst

print(f()) # prints [1]
print(f()) # prints [1, 1]

一般的な戦略は、Noneデフォルトパラメータを使用することです。 Noneが有効な値である場合は、シングルトンセンチネルを使用します。

NOTHING = object()

def f(arg = NOTHING):
    if arg is NOTHING:
        # no argument
    # etc.
36
Fred Foo

Noneを有効な引数として扱いたい場合は、**kwargパラメータ。

def function(arg1, arg2, **kwargs):
    kwargs.setdefault('arg3', default)
    arg3 = kwargs['arg3']

    # Continue with function

function("amazing", "fantastic") # uses default
function("foo", "bar", arg3=None) # Not default, but None
function("hello", "world", arg3="!!!")
0
killjoy