Ich versuche, eines meiner Hausaufgabenprobleme zu vereinfachen und den Code ein wenig zu verbessern. Ich arbeite mit einem binären Suchbaum. Im Moment habe ich eine Funktion in meiner Tree()
Klasse, die alle Elemente findet und in eine Liste einfügt.
tree = Tree()
#insert a bunch of items into tree
dann benutze ich meine makeList () Funktion, um alle Knoten aus dem Baum zu nehmen und sie in eine Liste zu setzen. Um die makeList()
Funktion aufzurufen , tue ich tree.makeList(tree.root)
. Für mich scheint sich das ein wenig zu wiederholen. Ich rufe das Baumobjekt bereits mit auf, tree.
daher tree.root
ist das nur eine Verschwendung von ein wenig Tippen.
Im Moment lautet die Funktion makeList:
def makeList(self, aNode):
if aNode is None:
return []
return [aNode.data] + self.makeList(aNode.lChild) + self.makeList(aNode.rChild)
Ich möchte die aNode-Eingabe zu einem Standardparameter machen, wie aNode = self.root
(was nicht funktioniert), damit ich die Funktion damit ausführen kann tree.makeList()
.
Die erste Frage ist, warum das nicht funktioniert.
Die zweite Frage ist, gibt es eine Möglichkeit, wie es funktionieren kann? Wie Sie sehen, ist die makeList()
Funktion rekursiv, sodass ich am Anfang der Funktion nichts definieren kann oder eine Endlosschleife erhalte.
BEARBEITEN Hier ist der gesamte angeforderte Code:
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
Antworten:
Larsmans beantwortete Ihre erste Frage
Können Sie bei Ihrer zweiten Frage einfach nachsehen, bevor Sie springen, um eine Rekursion zu vermeiden?
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
quelle
Dies funktioniert nicht, da Standardargumente zur Funktionsdefinitionszeit und nicht zur Aufrufzeit ausgewertet werden:
def f(lst = []): lst.append(1) return lst print(f()) # prints [1] print(f()) # prints [1, 1]
Die übliche Strategie besteht darin, einen
None
Standardparameter zu verwenden . WennNone
es sich um einen gültigen Wert handelt, verwenden Sie einen Singleton-Sentinel:NOTHING = object() def f(arg = NOTHING): if arg is NOTHING: # no argument # etc.
quelle
Sentinel
. Einfach benutzenNOTHING = object()
. Garantiert einen einzigartigen Singleton, nach dem Sie suchen könnenis
.foo(1, None)
und zufoo(1)
tun.None
ist der wichtigste. Der zweite Teil erstellt ein ObjektNOTHING
, verwendet dieses als Standardargument und prüft, ob das genaue Objekt übergeben wurde. Wenn Sie es ausblendenNOTHING
(nicht aus Ihrem Modul exportieren), kann es nicht vom Clientcode übergeben werden.is
vergleicht Objekte nach Speicheradresse.Wenn Sie
None
als gültiges Argument behandeln möchten , können Sie einen**kwarg
Parameter verwenden.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="!!!")
quelle