Today we’ll be comparing the == operator and the is operator. The former tests value equivalence, the latter tests object identity.
Let’s define two strings and compare them using the == operator and the is operator:
>>> s1 = "How are you?"
>>> s2 = "How are you?"
>>> s1 == s2
True
>>> s1 is s2
False
As you can see, s1 and s2 are two distinct objects, this is why the is operator returns False. But they have the same values, so the == operator returns True.
Now, here we have two lists:
>>> lst1 = [1, 2, 3]
>>> lst2 = [1, 2, 3]
Let’s assign one list to the other:
>>> lst1 = lst2
>>> lst1 == lst2
True
>>> lst1 is lst2
True
As you can see, now the lists lst1 and lst2 are referencing the same object. So, we have one object with two names.
We can use the operators also for other types. Here are some examples with integers, floating point numbers and dictionaries:
# ints
>>> n1 = 1254
>>> n2 = 1254
>>> n1 == n2, n1 is n2
(True, False)
# floats
>>> f1 = 41.324
>>> f2 = 41.324
>>> f1 == f2, f1 is f2
(True, False)
# dictionaries
>>> d1 = {'a': 3, 'b': 3}
>>> d2 = {'a': 3, 'b': 3}
>>> d1 == d2, d1 is d2
(True, False)
And here’s a more complicated example:
>>> lst1 = ['a', 'b']
>>> lst2 = ['a', 'b']
>>> lst3 = [['a', 'b'], lst1, lst2]
>>> lst3[0] == lst3[1] == lst3[2]
True
>>> lst3[0] is lst3[1] is lst3[2]
False
So, the 3 lists have the same values, but they are distinct objects, at three different locations in memory.
How about booleans? Have a look at these three bools:
>>> b1 = True
>>> b2 = True
>>> b1 == b2, b1 is b2
(True, True)
This time the booleans b1 and b2 are at the same address in memory, which means they are referencing the same object. Why is that? This is because of interning.
Interning is a mechanism of caching small integer numbers and short strings for the sake of optimization.
Anyway, the two booleans, True and False, are actually treated as numbers, 1 and 0 respectively, to be precise. For such small numbers interning works, so only one object is created in memory.
Here’s another small number, for which interning works:
>>> i1 = 8
>>> i2 = 8
>>> i1 == i2, i1 is i2
(True, True)
and a short string, for which interning also works:
>>> s1 = 'dance'
>>> s2 = 'dance'
>>> s1 == s2, s1 is s2
(True, True)
In most cases you’ll want to compare the values, not the identities, so the == operator will be usually the way to go. But if it matters whether we’re dealing with the same object or with distinct objects, the is operator is the option to choose.
Here you can watch the video version: