web-dev-qa-db-fra.com

Utilisation de self.xxxx comme paramètre par défaut - Python

J'essaie de simplifier l'un de mes problèmes de devoirs et d'améliorer un peu le code. Je travaille avec un arbre de recherche binaire. En ce moment, j'ai une fonction dans ma classe Tree() qui trouve tous les éléments et les met dans une liste.

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

puis j'utilise ma fonction makeList () pour prendre tous les nœuds de l'arbre et les mettre dans une liste. Pour appeler la fonction makeList(), je fais tree.makeList(tree.root). Cela me semble un peu répétitif. J'appelle déjà l'objet arbre avec tree. Donc le tree.root N'est qu'un gaspillage d'un peu de frappe.

À l'heure actuelle, la fonction makeList est:

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

Je voudrais faire de l'entrée aNode un paramètre par défaut tel que aNode = self.root (Qui ne fonctionne pas) de cette façon, je pourrais exécuter la fonction avec ceci, tree.makeList().

La première question est, pourquoi cela ne fonctionne-t-il pas?
La deuxième question est la suivante: y a-t-il un moyen de fonctionner? Comme vous pouvez le voir, la fonction makeList() est récursive donc je ne peux rien définir au début de la fonction ou j'obtiens une boucle infinie.

EDIT Voici tout le code demandé:

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 répond votre première question

Pour votre deuxième question, pouvez-vous simplement regarder avant de sauter pour éviter la récursivité?

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

Cela ne fonctionne pas car les arguments par défaut sont évalués au moment de la définition de la fonction, pas au moment de l'appel:

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

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

La stratégie courante consiste à utiliser un paramètre par défaut None. Si None est une valeur valide, utilisez une sentinelle singleton:

NOTHING = object()

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

Si vous souhaitez traiter None comme un argument valide, vous pouvez utiliser un **kwarg paramètre.

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