2011-04-05 12 views
41

Hola a todos, intento simplificar uno de mis problemas de tarea y mejorar un poco el código. Con lo que estoy trabajando es con un árbol de búsqueda binario. En este momento tengo una función en mi clase Tree() que encuentra todos los elementos y los pone en una lista.Uso de self.xxxx como parámetro predeterminado - Python

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

entonces utilizar la función de mi makeList() para tomar todos los nodos del árbol y los pone en una lista. Para llamar a la función makeList(), hago tree.makeList(tree.root). Para mí esto parece un poco repetitivo. Ya estoy llamando al objeto de árbol con tree. por lo que el tree.root es solo una pérdida de un poco de tipeo.

En este momento la función makeList es:

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

me gustaría hacer que la entrada ánodo de un parámetro por defecto como aNode = self.root (que no funciona) De esa manera podría ejecutar la función con esto, tree.makeList().

La primera pregunta es, ¿por qué no funciona?
La segunda pregunta es, ¿hay alguna manera de que pueda funcionar? Como puede ver, la función makeList() es recursiva, por lo que no puedo definir nada al comienzo de la función o recibo un ciclo infinito.

EDITAR Aquí es todo el código como solicitada:

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 
+1

¿Qué es lo que quiere con 'self' dentro de un método de nivel de módulo? Esto no hace absolutamente nada. Si makeList2() es un método de clase, proporcione el código correcto y no los fragmentos sin contexto. –

+0

makeList2() se suponía que era makeList(), lo edité – crh878

+0

¿Cómo no tiene sentido esto? Estoy intentando usar mi función makeList() más simple usando un parámetro predeterminado para la raíz del árbol en lugar de tener que llamarlo. – crh878

Respuesta

31

larsmans answered su primera pregunta

a su segunda pregunta, se puede simplemente mirar antes de saltar para evitar la repetición?

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 
26

No funciona porque los argumentos por omisión se evalúan en tiempo de definición de función, no en tiempo de llamada:

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

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

La estrategia común es usar un parámetro predeterminado None. Si None es un valor válido, utilice un centinela Singleton:

NOTHING = object() 

def f(arg = NOTHING): 
    if arg is NOTHING: 
     # no argument 
    # etc. 
+1

Puede omitir el 'Sentinel'. Solo usa 'NOTHING = object()'. Garantizado para producir un singleton único que puede verificar a través de 'is'. – delnan

+0

@delnan: buen punto, eliminado 'Sentinel'. –

+0

Recomiendo encarecidamente evitar que 'foo (1, None)' y 'foo (1)' hagan cosas diferentes. –

Cuestiones relacionadas