-1

I am trying to understand python behavior. I have the piece of code below: (TreeNode is a normal binary tree class)

class Solution:

    def anotherfunction(self, root, key):
        print(root)
        if(root.val == key):
            root = None
        print(root)
    
    def deleteNode(self, root: TreeNode, key: int) -> TreeNode:
        self.anotherfunction(root, key)
        print(root)

The output is as shown below:

TreeNode{val: 5, left: TreeNode{val: 2, left: None, right: None}, right: None}

None

TreeNode{val: 5, left: TreeNode{val: 2, left: None, right: None}, right: None}

I don't know why the root in my delete node function is not getting modified? I am new to Python3 and in C++ if I just pass the root using *& it works fine. I want to know what is the python equivalent of passing by reference?

khelwood
  • 55,782
  • 14
  • 81
  • 108
  • 1
    You cannot pass a variable by reference in Python. If you want a variable set to None, you have to set that actual variable to None. – khelwood Oct 27 '20 at 20:37
  • Python is by default by-assignment. You can always define your variable as `self.root` so it'd be basically the same object. – OmerM25 Oct 27 '20 at 20:40
  • Is there anyway I can set my root to None in anotherfunction and have it reflect in the deleteNode function? – user14531552 Oct 27 '20 at 20:41
  • You can set `root` to the return value of the function, and then return None from it. – khelwood Oct 27 '20 at 20:43
  • Make both your functions *return* the value of `root`, and let the caller assign the returned value to its own `root` variable. – trincot Oct 27 '20 at 20:43

2 Answers2

0

You can't really delete objects in python, all you can do is decrement reference counts by removing an object from a variable or container. Calling deleteNode and anotherfunction both added reference counts. All anotherfunction can do i decrement a reference count, and that happens anyway when the function returns.

In your case you could

class Solution:

    def anotherfunction(self, root, key):
        if(root.val == key):
            return root
        return None
    
    def deleteNode(self, root: TreeNode, key: int) -> TreeNode:
        root = self.anotherfunction(root, key)
        print(root)

This replaced your local variable root with either the same object or None. Note that the object itself may not be deleted, depending on how this method was called. The object gained a reference count when it was assigned to root during the function call. If the caller has a reference, the object survives.

sol = Solution()
my_node = Node(key="foo")
sol.deleteNode(my_node, "foo")
# still lives until all refs removed
del my_node
# finally got rid of it
tdelaney
  • 73,364
  • 6
  • 83
  • 116
-1

if variable in upper scope or internal scope before use in function has primitive values,it use copy of it and not change in upper scope but if in internal scope variable use references and in function change variable and new variable also use by references , it changed in upper scope

this happens because of The difference way of call and return between primitive and non_primitive variable

for example :

 def A(a):
    print(a)
    a = 4
    print(a)


if __name__ == '__main__':
    a = {"a": "s"}
    A(a)
    print(a)

this result is : {'a': 's'} 4 {'a': 's'}