The python identity operator is is quite frequently used to compare objects in python and often in places where the equality operator == should be used. In fact, you should almost always avoid using is
when comparing values. In this tutorial, we’d be covering the differences between the two operators and when to use them.
Identity vs Equality operators
Before discussing their differences, let’s see an example:
a = 50
b = 50
print("Identity: ", a is b)
print("Equality: ", a == b)
What you think should the output be in this case? Should we get True
for both? Or is there a difference between the two? The following is the output we get on executing the above code snippet:
Identity: True
Equality: True
Interesting, it does seem that both the identity operator is
and the equality operator ==
do the same thing since we’re getting the same results. But wait. Before you conclude that both of them are practically the same thing, try executing the following code snippet:
a = 5000
b = 5000
print("Identity: ", a is b)
print("Equality: ", a == b)
The above code gives the output:
Identity: False
Equality: True
Wait. What just happened?
Now would be a good time to define what these operators are and how they’re different. Remember, everything in python is an object and each object is assigned a memory location.
- Identity Operators: Python identity operators (
is
,is not
) are used to compare objects based on their identity. In the CPython interpreter, which you’re most likely to be using, the identity of an object refers to its location in memory. Other interpreters may have different ways of defining identity. - Equality Operators: Python equality operators (
==
,!=
) are used to compare objects based on their values. It invokes the__eq__()
class method of the left object which defines the rules for checking equality. But generally, these rules are defined such that if two objects have the same value irrespective of their memory locations, the equality operator==
results inTrue
.
For more on operators in python refer to this guide.
Introductory ⭐
- Harvard University Data Science: Learn R Basics for Data Science
- Standford University Data Science: Introduction to Machine Learning
- UC Davis Data Science: Learn SQL Basics for Data Science
- IBM Data Science: Professional Certificate in Data Science
- IBM Data Analysis: Professional Certificate in Data Analytics
- Google Data Analysis: Professional Certificate in Data Analytics
- IBM Data Science: Professional Certificate in Python Data Science
- IBM Data Engineering Fundamentals: Python Basics for Data Science
Intermediate ⭐⭐⭐
- Harvard University Learning Python for Data Science: Introduction to Data Science with Python
- Harvard University Computer Science Courses: Using Python for Research
- IBM Python Data Science: Visualizing Data with Python
- DeepLearning.AI Data Science and Machine Learning: Deep Learning Specialization
Advanced ⭐⭐⭐⭐⭐
- UC San Diego Data Science: Python for Data Science
- UC San Diego Data Science: Probability and Statistics in Data Science using Python
- Google Data Analysis: Professional Certificate in Advanced Data Analytics
- MIT Statistics and Data Science: Machine Learning with Python - from Linear Models to Deep Learning
- MIT Statistics and Data Science: MicroMasters® Program in Statistics and Data Science
🔎 Find Data Science Programs 👨💻 111,889 already enrolled
Disclaimer: Data Science Parichay is reader supported. When you purchase a course through a link on this site, we may earn a small commission at no additional cost to you. Earned commissions help support this website and its team of writers.
Okay, so why did the identity operator is
result in True
in the first example and False
in the second? Surely, different variables should have different memory locations. Right? Let’s see for ourselves:
The python in-built function id()
gives the memory location of an object. Let’s use it to see the locations referred to by the variables in the above two examples.
a = 50
b = 50
# location
print("Location of a:", id(a))
print("Location of b:", id(b))
# test
print("Identity: ", a is b)
print("Equality: ", a == b)
Output:
Location of a: 140733847780672
Location of b: 140733847780672
Identity: True
Equality: True
Since a
and b
had the same location the identity operator is
resulted in True
. Let’s see if that’s the case with the 2nd example:
a = 5000
b = 5000
# location
print("Location of a:", id(a))
print("Location of b:", id(b))
# test
print("Identity: ", a is b)
print("Equality: ", a == b)
Output:
Location of a: 1947716996112
Location of b: 1947716995856
Identity: False
Equality: True
Here, we find that a
and b
have been given different memory locations and thus the identity operator is
resulted in False
even though they had the same values.
Note that when variables a
and b
were assigned with value 50 they had the same memory location but when assigned with the value 5000, they had different memory locations. A good question to ask now would be –
Why did variables with small (but same) values get assigned to the same memory location?
This happens because the CPython interpreter interns smaller numbers at fixed memory locations. It means that the interpreter instantiates these values only once and it just have to look for its memory address whenever it is referenced. This is done because such values (like small numbers) are quite frequently used. Depending on your interpreter the range of such numbers might vary but it’s generally -5 to +256
.
a = 256
b = 256
print(id(a))
print(id(b))
Output:
140733847787264
140733847787264
For 256, we get the same location due to interning.
a = 257
b = 257
print(id(a))
print(id(b))
Output:
1947707102640
1947707102672
But from 257 we see that we get different locations since they are not interned. There are other objects as well that are interned by the python interpreter.
When should you use the identity operator?
The identity operators are actually quite useful when asserting whether an object is a specified singleton (objects with only one reference in memory) in python like None
, True
, or False
because they check for identity and not run any other method based checks like ==
When you do –
a is None
The interpreter can only compare for identity and that cannot be overruled. Meaning, it’s a guaranteed check whether a
is a reference to the None
object and not something else.
With
a == None
The ==
operator invokes the a.__eq__()
method which can give strange results depending on how it’s defined. See the example below –
class A:
def __eq__(self, other):
return True # I think I'm equal to everything
a = A()
print(a == 1)
print(a == None)
print(a is None)
Output:
True
True
False
You can see in the above example that the object a
has been defined so as to all always return True
whenever the class method __eq__()
gets invoked, which is the case when you use ==
for comparison. And you should prefer is
in such cases as it does not leave room for accidental results where the implementation could be different than expected.
Conclusion – Things to remember
Knowing when to use and not use the identity operator can save you a lot of time on future hair pulling. The following are the key pointers to remember –
- Objects with the same value are often stored at different memory locations. Only a handful number of values are primed by the interpreter.
- Always use the operators
==
or!=
when comparing values. - Use the identity operators to compare objects based on their identity. Example, when comparing with singleton objects like
None
,True
,False
, etc.
For more, refer to this detailed article by Real Python.
Subscribe to our newsletter for more informative guides and tutorials.
We do not spam and you can opt out any time.