Difference Between the == and is Operators in Python
In Python, the ==
operator checks if the values of two objects are equal, while the is
operator checks if two objects are identical.
Value comparison using the ==
operator
The ==
operator returns True
if the values of the two objects are equal and False
if they are not.
a = 100
b = 100
c = 200
print(a == b)
# True
print(a == c)
# False
On the other hand, the !=
operator returns True
if the values of the two objects are not equal and False
if they are equal.
print(a != b)
# False
print(a != c)
# True
Value comparison for numbers
For numeric types such as integers (int
), floating point numbers (float
), and complex numbers (complex
), values are compared even if the types are different.
print(100 == 100.0)
# True
print(100 == 100 + 0j)
# True
Additionally, the booleans (bool
) are a subclass of the integers (int
). True
is treated as 1
, and False
is treated as 0
.
print(1 == True)
# True
print(0.0 == False)
# True
To check if both the value and type are equal, use type()
and and
.
- Get and check the type of an object in Python: type(), isinstance()
- Boolean operators in Python (and, or, not)
a = 100
b = 100.0
print(a == b)
# True
print(a == b and type(a) == type(b))
# False
Note that strings (str
) are not considered equal to numbers despite their content. To compare a string's value with a number, convert the string to a number using int()
or float()
.
print(100 == '100')
# False
print(100 == int('100'))
# True
Identity comparison using the is
operator
The is
operator returns True
if the two objects are identical and False
if they are not.
Even if the values are the same (the result of ==
is True
), is
returns False
if the objects are different.
l1 = [1, 2, 3]
l2 = [1, 2, 3]
print(l1 == l2)
# True
print(l1 is l2)
# False
When one variable is assigned to another, both point to the same object, and is
returns True
.
l3 = l1
print(l1 is l3)
# True
For mutable objects like lists and dictionaries, if two variables point to the same object and one is changed, the other also changes.
l1[0] = 100
print(l1)
# [100, 2, 3]
print(l2)
# [1, 2, 3]
print(l3)
# [100, 2, 3]
In contrast to the is
operator, the is not
operator returns True
if the two objects are not identical and False
if they are identical.
print(l1 is not l2)
# True
print(l1 is not l3)
# False
Identity is determined by the id() function
The built-in function id()
is used to determine the object's identity.
print(id(l1))
# 4388188480
print(id(l2))
# 4388187456
print(id(l3))
# 4388188480
You can verify that the same objects (in the example, l1
and l3
) have the same identification value.
Identity comparison for immutable types
Be cautious when using is
and is not
comparisons for immutable objects like integers (int
) and strings (str
).
When creating a new object, a reference to an existing object may or may not be returned.
For example, when creating an int
value in the range of -5
to 256
, a reference to an existing object is returned. However, values outside this range are created as separate objects.
The current implementation keeps an array of integer objects for all integers between
-5
and256
. When you create an int in that range you actually just get back a reference to the existing object. Integer Objects — Python 3.11.3 documentation
a = 256
b = 256
print(a is b)
# True
a = 257
b = 257
print(a is b)
# False
For strings (str
), those containing only alphanumeric characters and underscores (_
) are cached, and a reference to the cached object is returned. However, strings with other characters are created as separate objects.
a = 'abc_123'
b = 'abc_123'
print(a is b)
# True
a = 'abc_123?'
b = 'abc_123?'
print(a is b)
# False
Results may vary depending on the code structure, such as creating identical objects when assigning values to two variables in the same line.
a, b = 257, 257
print(a is b)
# True
a, b = 'abc_123?', 'abc_123?'
print(a is b)
# True
Also, these are the results when executed in CPython 3.11, and may vary depending on the implementation or version.
Although is
is faster than ==
, and you may use it if you understand the specifications, it is generally recommended to use ==
instead of is
when comparing immutable objects.
==
operator can be overloaded, is
operator cannot
The ==
and !=
operators have corresponding special methods __eq__
and __ne__
, which can be overloaded.
class MyClass:
def __eq__(self, other):
return '__eq__'
def __ne__(self, other):
return '__ne__'
my_obj = MyClass()
print(my_obj == 100)
# __eq__
print(my_obj != 100)
# __ne__
The above example is an extreme case where ==
and !=
operations always return '__eq__'
and '__ne__'
, but user-defined class ==
and !=
operations may be customized.
On the other hand, there are no corresponding special methods for the is
and is not
operators, and they cannot be overloaded. They always compare and determine the identity of objects.
Check for None
with is None
or is not None
None
is a built-in constant that represents the absence of a value.
In Python's coding convention PEP8, comparisons with None
should use is
and is not
instead of ==
and !=
.
Comparisons to singletons like
None
should always be done withis
oris not
, never the equality operators. PEP 8 – Style Guide for Python Code | peps.python.org
a = None
print(a is None)
# True
print(a is not None)
# False
Although not explicitly stated in PEP8, the following reasons can be considered:
None
is a singleton (the only instance of NoneType), so there is no concern that the result ofis
will change depending on the value, as in the examples of integers and strings mentioned above.is
andis not
are not overloadable and are safe, while==
and!=
may be customized by operator overloading.is
andis not
are faster than==
and!=
.
For example, depending on the __eq__
implementation, == None
might return True
for non-None values. However, is None
always correctly determines the value.
class MyClass:
def __eq__(self, other):
return True
my_obj = MyClass()
print(my_obj == None)
# True
print(my_obj is None)
# False
Note that nan
, which represents a "not a number", is a float
value and is different from None
. To check for nan
, use math.isnan()
or numpy.isnan()
.