0
class Node:
    """A Tree Node with 3 attributes: l_child, r_child and data"""
    def __init__(self, val):
        self.data = val
        self.l_child = None
        self.r_child = None

class BST(object):
    """Implement a Binary Search Tree class"""
    def __init__(self):
        self.root = None
        print "Initial root", self.root

    def insertRecur(self, node, data):
        if node is None:
            node = Node(data)
        else:   
            if data < node.data:
                insertRecur(node.l_child, data)
            if data > node.data:
                insertRecur(node.r_child, data)

    def Insert(self, data):
        self.insertRecur(self.root, data)

Sorry, guys this is actually what my original code is. I want to use Python to implement a binary search tree class. and I want to do like that

test = BST()
test.Insert(1)
print test.root

and test.root is None

3 Answers3

2

Of course it will still be None. You didn't assign it the value. Should be.

def Insert(self, data):
    self.data = data
    self.Recur(self.data, data)

However, the function

def Recur(self, node, data):
    if node is None:
        node = data

achieves absolutely nothing (and never did) because node is not used anywhere, only assigned to.

EDIT: After your updated code, we can see what you're trying to do. The reason your test.root is None is because you never assign it. The problem is here:

def insertRecur(self, node, data):
    if node is None:
        node = Node(data)

When this function is called from self.insertRecur(self.root, data), it is POINTING to the same value as self.root which is None. When you do node = Node(data) you are reassigning node to point to Note(data), this does not reassign self.root. Do this instead :

class Node:
    """A Tree Node with 3 attributes: l_child, r_child and data"""
    def __init__(self):
        self.data = None
        self.l_child = None
        self.r_child = None

class BST(object):
    """Implement a Binary Search Tree class"""
    def __init__(self):
        self.root = Node()
        print "Initial root", self.root

    def insertRecur(self, node, data):
        if node.data is None:
            node.data = data
        elif data < node.data:
            node.l_child = node.l_child or Node()
            self.insertRecur(node.l_child, data)
        else:
            node.r_child = node.r_child or Node()
            self.insertRecur(node.r_child, data)

    def Insert(self, data):
        self.insertRecur(self.root, data)
logee
  • 5,017
  • 1
  • 26
  • 34
  • If the OP uses your edits, what *exactly* does the resulting code accomplish? `Recur` still has no meaning in that case! – jpaugh Jul 27 '15 at 04:14
  • @jpaugh Yes, I am aware of that. I just answered his question on why there was no `example.data` and was pointing that out to him that `Recur` does nothing. I didn't change it cause I don't know his intention in that method. – logee Jul 27 '15 at 04:25
  • Ok. My downvote was a little harsh. I made a minimal edit so that I could retract it. – jpaugh Jul 27 '15 at 04:36
  • Sorry, I change the example code to the original one. I want to implement a BST – Jason Yuan Jul 27 '15 at 05:34
  • @user2341963 Thanks, Man! But I still did get the idea why your code works compared with mine. `self.root = None` vs `self.root = Node()` What is the topic for these things that I can take a deeper look? Thanks – Jason Yuan Jul 27 '15 at 21:54
  • @JasonYuan I think your problem comes in from how you understand the way python passes parameters. You should check out [this](http://stackoverflow.com/questions/986006/how-do-i-pass-a-variable-by-reference) post. Hope it helps – logee Jul 28 '15 at 00:08
0

You just assign the value of self.data to node, not the variable self.data itself. What you called in Insert function is exactly:

self.Recur(None, 5)

I guess what's you wanna is:

self.Recur(*self.data, 5)

But there's no pointer in python. You can merge the code of Recur into Insert, or if you wanna maintain both Recur and Insert:

    def Recur(self, node, data):
        if node is None:
            node = data
        return node

    def Insert(self, data):
        self.data = self.Recur(self.data, data)
LittleQ
  • 1,860
  • 1
  • 12
  • 14
0

Your example would work in some programming languages. (For example C allows this, via pointer references.) The reason it doesn't work here is because of how the semantics of method-calling is defined in Python.

Name binding in Python

When you write

self.data = None

this assigns a new name (self.data) to the object None.

With self.Recur defined as

def Recur(self, node, data):
    if node is None:
        node = data

the following gives a new name to None in the context of the Recur method: node.

self.Recur(self.data, data)

However, this new name (node) in the inner scope for the same object has no co-relation to the other name (self.data) in the outer scope.

When you write

node = data

this assigns the name node to a new value, namely the value to which the name data refers. Again, this does not affect the name self.data. For more information, check out this blog post.

How to do what you want

On the other hand, if you want Recur to be able to assign a value to any attribute of the test object, it can be done. Here is one way to achieve it:

class test:
    def __init__(self):
        self.data = None

    def Recur(self, nodeName, data):
        if self[nodeName] is None:
            self[nodeName] = data;

    def Insert(self, data):
        self.Recur("data", data) 

    __getitem__ = self.__getattr__
    __setitem__ = self.__setattr__

NB: This code is untested

This allows Insert to choose the name ("data") to which Recur assigns a value. Recur, for its part, uses the dict-key get-item syntax of Python to assign a value to the key data in our quasi-dict object; however, we set the get-item and set-item semantics to be the same as the get-attribute and set-attribute semantics with the last two lines — this ensures that self["name"] means the same thing as self.name. A less mysterious implementation would be:

def __getitem__(self, key):
    return self.__getattr__(key)
jpaugh
  • 6,634
  • 4
  • 38
  • 90