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
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
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.
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="!!!")