For some types in Python, the is operator seems to be equivalent to the == operator. For example:
>>> 1 is 1
True
>>> "a spoon" is "a spoon"
True
>>> (1 == 1) is (2 == 2)
True
However, this is not always the case:
>>> [] == []
True
>>> [] is []
False
This makes sense for mutable types such as lists. However, immutable types such as tuples seem to display the same behavior:
>>> (1, 2) == (1, 2)
True
>>> (1, 2) is (1, 2)
False
This raises several questions:
- Is the
==/isequivalence related to immutability? - Are the behaviors above specified, or an implementation detail?
- Most importantly (and basically), how can I know if an assignment will result in a copy of an object being made, or a reference to it being made?
Update:
If assignment is always by reference, why doesn’t the following print 2?:
>>> a = 1
>>> b = a
>>> a = 2
>>> b
1
Why isn’t this equivalent to the following C snippet:
int a = 1;
int *b = &a;
a = 2;
printf("%d\n", *b);
Apologies for the newbness of this question, but I am a Python novice and feel that it is important to understand this. Is there any reading you would recommend to understand these sort of issues?
The
isoperator tests if two objects are physically the same, that means if they have the same address in memory. This can also be tested using theid()function:The
==operator on the other hand, tests for semantical equality. This can also be overridden by custom classes by implementing the__eq__()function. Semantically, two different lists are equal if their elements are all equal, but physically they will be different objects.Immutable types like strings and tuples might be pooled by the Python implementation, so that two literal string objects are in fact physically identical. But this does not mean that you can always use
isto compare those types, as demonstrated in the following example:Assignments in Python always bind the reference to an object to a variable name and never implies a copy.
UPDATE
Analogous to C, think of Python variables always being pointers:
Roughly equivalent to: