Reputation: 9
I had some problem while writing the Join operation on red-black trees. I found what's causing it and tried to simplify it into the following code (because whole blocks of red-black tree code are pretty much unreadable).
So can anyone explain to me why the final line evaluates to False? I think that as the a = b line only assign pointers, c.left should now point to b.
class RedBlackTreeNode:
def __init__(self, key, color):
self.key, self.color, self.left, self.right, self.parent = key, color, None, None, None
a = RedBlackTreeNode(None, False)
b = RedBlackTreeNode(None, False)
c = RedBlackTreeNode(1, False)
c.left = a
a = b
print(c.left == b)
>>> False
Upvotes: 0
Views: 193
Reputation: 15887
Good old name and value confusion, here with a dash of complicated code. Let's work backwards.
First, you're comparing using ==
. Here those are both objects of type RedBlackTreeNode
, which doesn't override the equality behaviour. So it's actually an identity test.
Secondly we trace back where the two operands c.left
and b
come from. We find that c.left
was assigned the value of a
before a
was changed to refer to b
. Therefore, c.left
refers to the node originally bound as a
but no longer known under that name.
In C-style pointer language, every variable is actually a pointer (reference), and pointers are always copied by value; there is no type for pointer to pointer, so they can't alter each other even though they can point to the same data.
Python's objects are entities in their own right, and variables are merely names referring to objects. Therefore reassigning a
only meant there was one less way to find the object it previously referred to. Each name (whether in your locals, the module's globals or an object like c
) only refers to some object, they know nothing of each other (though there may be reference counts to track their existence).
Ned Batchelder's article on Python Names and Values might clear this up a bit.
It's also possible for things to look like these names but redirect to more complex behaviour. That's what custom attribute access and properties do, particularly for things that translate like ctypes
structures.
Upvotes: 1
Reputation: 50864
a
is just a name, not a pointer like in C. You can even do a = 1
, it won't change the RedBlackTreeNode
in c.left
to int
.
c.left
has the value of a
has it was assigned in a = RedBlackTreeNode()
. To change it you need to assign c.left =
again.
*In some IDEs you can even see a warning on a = b
: Locale variable 'a' value is not used
.
Upvotes: 0