Home > front end >  How to resolve a 'NoneType Error' on my code?
How to resolve a 'NoneType Error' on my code?

Time:04-10

I'm trying to make a binary tree deletion code on python. In some reason, I got an error 'AttributeError: 'NoneType' object has no attribute 'right''.

When I tried to print the type of variable 'root', it says <class 'NoneType'>.

Also when I changed the 'root = None insert(root, 50)' to 'root = Node(50)', it worked.

I'm guessing that there is some error on Class Definition or insert function. Can anybody help me?

import random
from timeit import default_timer as timer


class Node(object):
    def __init__(self, key, parent=None):               
        self.key = key
        self.left = None
        self.right = None
        self.parent = parent


def insert(node, key):
    if node is None:
        node = Node(key)
        return node
    elif key < node.key:
        node.left = insert(node.left, key)
        node.left.parent = node
    else:
        node.right = insert(node.right, key)
        node.right.parent = node
    return node


def delete(node):
    if node.parent is None:
        node = delete_node(node)    # root
    elif node == node.parent.left:
        node.parent.left = delete_node(node)
    else:
        node.parent.right = delete_node(node)


def delete_node(r):
    if r.left is None and r.right is None:
        return None
    elif r.left is not None and r.right is None:
        return r.left
    elif r.left is None and r.right is not None:
        return r.right
    else:
        s = r.right
        while s.left is not None:
            sparent = s
            s = s.left
        r.key = s.key
        if s == r.right:
            r.right = s.right
        else:
            sparent.left = s.right
        return r


root = None
insert(root, 50)
insert(root, 99)
insert(root, 78)
insert(root, 57)
insert(root, 80)
insert(root, 4)
insert(root, 64)
insert(root, 35)
insert(root, 58)
insert(root, 33)

print(root.right.left.key)
start = timer()
delete(root.right.left)
print(timer() - start)
print(root.right.left.key)

CodePudding user response:

The insert function creates the first node if it doesn't exist, but you ignore the return value. Instead, you should reassign it to node: root = insert(root, 50), etc.

CodePudding user response:

You need to get the return type. If you reassign a variable in a function, it remains in the function scope. The variable is only mutated of it is already the object. That’s why your second example worked: you passed in a Node which was changed, while your first example didn’t: you created a Node and returned it.

You’ll want to reassign root in your first insert function.

root = assign(None, 50)
assign(root, 99)
…

As an aside, I often find it easier to split these functions into two. Your first one which returns a new Node might be called create, and you simply pass a value. After that you can call assign with the root node.

CodePudding user response:

The problem has to do with the fact that when you assign a variable inside a function, that variable is edited locally, not globally. The easiest fix is to return the value from insert, delete, etc. instead of trying to assign it inside your functions:

def some_func(x):
    if x is None:
        return 1
    else:
        return x   1

x = None
x = some_func(x)
  • Related