2017-07-26 2 views
0

Ich habe ein Tupel wie dieses.ist kein Objekt in Python veränderbar?

t = (5, (3, (20, none, none), (21, none, none)), (10, (1, none, none), none)) 

Ich möchte einen Baum daraus bauen. Baumklasse sieht so aus.

class TreeNode(object): 
    def __init__(self,x=None,l=None,r=None): 
     self.x = x 
     self.l = l # left node 
     self.r = r # right node 

Ich baue Baum rekursiv. Ich überprüfe, ob der aktuelle Knoten None ist, und setze dann den aktuellen Knoten auf eine neue TreeNode Klasse. Aber das funktioniert nicht wie erwartet.

def build(current_node, tupl): 
    if tupl: 
     if current_node is None: 
      current_node = TreeNode() # I think this removes link to the trees node. 
     current_node.x = tupl[0] 
     build(current_node.l, tupl[1]) 
     build(current_node.r,tupl[2]) 

hier ist, wie ich bauen rufen Funktion

root = TreeNode() # TreeNode is tree class 
build(root,t) 
# I try to print the tree level by level but tree only has root node 

Aber diese Build-Funktion funktioniert gut.

def build(curr,t): 
    if t: 
     curr.x = t[0] 
     try: 
      if t[1] is not None: 
       curr.l = TreeNode() 
       build(curr.l,t[1]) 
     except Exception: 
      pass 
     try: 
      if t[2] is not None: 
       curr.r = TreeNode() 
       build(curr.r,t[2]) 
     except Exception: 
      pass 

Ich versuche zu verstehen, warum die erste Build-Funktion fehlschlägt.

+6

Was ist falsch an Ihrem Code - gibt es eine Fehlermeldung oder eine falsche Ausgabe? Bitte schreiben Sie den Traceback oder die erwartete und tatsächliche Ausgabe. Übrigens ist die "ausgenommen Ausnahme" gefährlich und kann Fehler leicht verstecken. https://stackoverflow.com/questions/21553327/why-is-except-pass-a-bad-programming-practice. Mir ist auch nicht klar, wie der Fragekörper mit dem Titel verwandt ist - aber nein, keiner ist veränderbar. – perigon

+0

Danke, ich werde meine Frage bearbeiten und auf mein Problem hinweisen. Ich verwende try catch, um zu überprüfen, ob der Index existiert. Wie kann ich es ohne Versuch fangen? –

Antwort

2

In Python können Sie Variablen innerhalb einer Funktion nicht neu zuweisen, und diese Werte sind für den aufrufenden Kontext sichtbar. Durch das Aufrufen von current_node = TreeNode() wird current_node einem neuen Objekt zugewiesen, das für außen nicht sichtbar ist.

def build(current_node, tupl): 
    if tupl: 
     if current_node is None: 
      current_node = TreeNode() 
     current_node.x = tupl[0] 

     build(current_node.l, tupl[1]) 
     build(current_node.r,tupl[2]) 

In Ihrem zweiten Beispiel sind vorbei Sie in einem TreeNode Beispiel, es ist Attribut dann manipulieren und Neuzuweisung es nicht. Daher beziehen sich Curr.l./Curr.r im aktuellen Kontext und curr im nächsten Aufruf immer noch auf das gleiche Objekt.

def build(curr,t): 
    if t: 
     curr.x = t[0] 
    .... 
    if t[2] is None: 
     curr.r = TreeNode() 
    .... 
    # reference link is not broken 
    build(curr.r, t[2]) 
+0

Ihre Unterscheidung zwischen primitiven Typen und komplexen Typen ist nicht korrekt. Python hat keine anderen Arten von Typen. Alle Objekte werden gleich behandelt, wenn sie als Argumente übergeben werden. Die Aufrufkonvention von Python lässt sich am besten als "Bindung nach Namen" beschreiben, da alle Funktionsparameter lokale Variablen sind, die an die Objekte gebunden sind, die als Argumente übergeben werden. – Blckknght

+0

Sie haben Recht. Ich dachte, dass es gleichwertig ist, aber das ist es nicht. –

Verwandte Themen