What’s the difference between “is” and “==” in Python? | by Ahmed Besbes | Towards Data Science

When we compare objects in Python, we usually use the ==operator. We may sometimes be tempted to use the is operator as well to perform the same task.
Are these two operators any different?
This is a short post to explain the nuances between the two and provide a recommendation as to when to use which.
I personally never knew until I looked it up. It’s actually very simple to understand and also important to know.
== is for value equality. It's used to know if two objects have the same value.
is is for reference equality. It's used to know if two references refer (or point) to the same object, i.e if they're identical. Two objects are identical if they have the same memory address.
Two objects having equal values are not necessarily identical.
Put simply: ==determines if the values of two objects are equal, while isdetermines if they are the exact same object.
Or even simpler: the isstatement is syntactic sugar for id(a) == id(b)
*id() is a built-in function in Python. It accepts a single parameter and is used to return the identity of an object.
Let’s define a variable a to hold a list and let’s affect it to a variable b.
a and breference the same object in memory and this is something we can check using the id function. (the id is guaranteed to be unique among simultaneously existing objects).
a and bhave therefore the same id and hence the statement a is b is true.
a = [1, 2, 3]b = aid(a)# 140545544215872id(b)# 140545544215872a is b# Truea == b# True
Let’s now make a copy of the list avia the slice operator. A copy should create a new object in memory, with a new address, thus a new id is allocated.
c = a[:]id(a)# 140545544215872id(c)# 140545544587008
therefore:
a is c# Falsea == c# True
Here a and c point to two different objects in memory even if their values are equal.
Let’s run this small example.
>>> a = 1000>>> b = 1000>>> a == bTrue>>> a is bFalse
The behaviour is expected, just like what we saw in the previous example.
Let’s now replace 1000 with 100.
>>> c = 100>>> d = 100>>> c == dTrue>>> c is dTrue
What happened here? this is inconsistent with the previous result.
It turns out the reference implementation of Python caches integer objects in the range -5..256 as singleton instances for performance reasons.
The same thing happens for strings as well.
PEP 8, the official Python style guide for the standard library also mentions two use-cases for is:
Comparisons to singletons like None should always be done with is or is not, never the equality operators.
Also, beware of writing if x when you really mean if x is not None — e.g. when testing whether a variable or argument that defaults to None was set to some other value. The other value might have a type (such as a container) that could be false in a boolean context!
Two objects are identical if they have the same memory address
Two identical objects have equal values but two objects with equal values are not necessarily identical
Use is to check the identity and use== to check the equality.
Use is when you compare to singletons like None and == in most other cases: this is a safe choice.