Comparing Objects
00:00
I want to talk about the difference between the is
operator and the equals equals (==
) operator because I know that this is often a point of confusion for Python developers, and I’ve been trying to come up with an example that really boils it down to a minimal example necessary to understand this distinction.
00:22
And I think I got a pretty good shot at this, so bear with me. So, at the end of the video, you’re going to know the difference between is
and ==
, and you’re going to know when to apply them.
00:31 So, the key thing here is that there’s a difference between two things being identical—two objects being identical—and them being equal.
00:40 Like, there’s a semantic difference; there’s a difference in meaning. For example, when I grew up, our neighbors had twin cats, so there were two cats that looked pretty much exactly the same, but of course, they were two different cats. I mean, you wouldn’t say, like, “Oh, that’s the same cat,” right?
01:00
That would be crazy, because there’s two of them. And I’m going to keep stretching that analogy even thinner, so bear with me. All right, so they’re two different cats and they’re two different entities, but they look the same. Like, you could say, “Oh, they’re equal.” But really what this example shows is that there’s a difference between two things being equal and two things being identical, and that difference is really important if you want to understand the difference between is
and the ==
operator. So, let’s start with the ==
operator first.
01:37
This guy here, it compares by checking for equality. So, if these cats were Python objects and we compared them with the ==
operator, we’d get, “Hey, these cats are equal!” as an answer because they have the same properties—they look the same. Now, on the other hand, the is
operator compares identities.
01:58
So if we compared our seemingly identical cats, or identical-looking cats, with the is
operator, then we’d get the answer that “Well, they’re two different cats,” right?
02:11 “They’re not the same cat. There’s two of them. Are you crazy?” Before I get all tangled up in this cat analogy, let’s actually come up with some Python code here.
02:20
So, what we’re going to do first is we’re going to create a new list object, just create this new list [1, 2, 3]
. Then, we’re going to create another variable that points to the same list.
02:32
So now, these two variables, a
and b
, they’re pointing to the same list, so when we inspect a
, we can see here, “Okay, this is the contents we put in earlier.” And if we inspect b
, then we get the same result. Now, at this point, we know that they kind of look the same, right?
02:52
So if we compare them with the ==
operator, we get True
as the answer because, well, they look the same. They have seemingly the same content.
03:04
Now what that doesn’t tell us, however, is whether or not a
and b
are actually the same object. I mean, in this case, we know because we created them and we assigned b
to point to the same object that a
points to—
03:23
but suppose we didn’t know, right? Like, how could we find out? And this is where the is
operator comes in. So, if we went a is b
, then in this case, Python would tell us, “Yeah, they’re the same object. They are the same thing.” And that would mean if I go in and change a
—by let’s say, putting in a string—if I change a
, that would also change b
because they’re pointing to the same underlying object, right? And so now, I’m actually going to undo this and just create a new list here and then replay everything I did before. So now, I undid this change here where I added this string.
04:07
So, what we’re going to do now is we’re going to create a new copy of this list that we’re going to call c
. And the way we can do that is just by calling the list()
function, the built-in list()
function on a
again. What that’s going to do is it’s going to create a shallow copy that will look exactly the same.
04:29
So, let’s take a look at a
again, look at b
again, and then look at c
. And you can see here, they all look exactly the same, right?
04:37 If you’re just looking at their contents, they look exactly the same.
04:42
Now, this is where it gets interesting, right? Because when I go and compare a
to c
, then we get the answer, “Okay, they look identical.
04:53
They are considered equal.” Now, if I go and do a is c
, then we get a different result, because Python tells us, “Hey, they’re not the same object. They might look identical, but they’re not the same fricking cats.
05:06
They’re two different cats that just look the same.” Right? They both have black fur and the same eye color and whatnot, but they’re two different cats. And really, this is the key distinction between ==
and the is
operator,
05:23
because the is
operator, or an is
expression—it evaluates to True
if two variables point to the same identical object. And the ==
operator, or an ==
expression, evaluates to True
if both objects are equal, or have the same contents.
05:42 But they’re not necessarily the same object—like, we don’t care about that. All right. So, I hope this clarified this difference to you. Just think of cats.
05:52
Every time you’re going to have to make a decision between ==
and is
just think of twin cats. I mean, think of cats all day! You can also think of dogs—it works the same way with dogs.
06:01 But that’s really the key distinction you need to remember.
varelaautumn on Sept. 21, 2020
I found the id
to be the most helpful thing for me understanding is
vs ==
.
I think these two examples lay out the main differences:
# Lists (mutable)
a = [1,2,3]
b = a
c = [1,2,3]
print(f'id of c: {id(a)}')
print(f'id of c: {id(b)}')
print(f'id of c: {id(c)}')
print(f'a is b: {a is b}')
print(f'a is c: {a is c}')
>>> 'id of a: 2081950383616'
>>> 'id of b: 2081950383616'
>>> 'id of c: 2081950373760'
>>> 'a is b: True'
>>> 'a is c: False'
# Tuples (immutable)
a = (1,2,3)
b = a
c = (1,2,3)
print(f'id of a: {id(a)}')
print(f'id of b: {id(b)}')
print(f'id of c: {id(c)}')
>>> 'id of a: 2081946553216'
>>> 'id of b: 2081946553216'
>>> 'id of c: 2081946553216'
>>> 'a is b: True'
>>> 'a is c: True'
The id
represents a unique number pointing to a specific memory address of the object.
Tuples are immutable, just like an integer. Tuple(1,2,3) is Tuple(1,2,3) is no different than saying “1 is 1”. They can’t change so there is no reason for that unique value to have anything but 1 location in memory.
Lists on the other hand are mutable. You may have 5,000 independent variables which are all initially set to the value [1,2,3]. If all those 5,000 variables were pointing to the same memory address which held the list value [1,2,3]. Then altering any one of those 5,000 variables, would change every other variable at that memory address. Obviously that’d be a messy disaster.
So instead every list which happens to share the same value still maintains their own memory address/id, so they can mutate independently of others which happen to have the same value. Hence in the example, “a is not c”. They point to two different lists at two different memory addresses.
The reason b is a, is because b was set equal to a. When you say ‘b = a’, you’re pointing b to the same memory address that a is pointing at. Both point to the same list which happens to contain [1,2,3]. So they have the same id, and hence ‘b is a’.
It’s all about what memory address they’re pointing at, and not what value they are. (Though if the object is immutable, there’s only going to be one memory address for any specific value, “1 is 1”, “5 is 5”, “tuple(5,4) is tuple(5,4)”, “ ‘b’ is ‘b’ “, “True is True”, “False is False”, etc)
Dan B on Nov. 10, 2020
I really think a quiz would help me learn this.
Robot on July 5, 2023
Nawh, Dan don’t beat that dead cat. The dead ringer for the first one.
You must own this product to join the conversation.
rorydaulton on June 9, 2020
This is a pretty good lesson. But I think you could have made the difference between
is
and==
even more clear by changing the value ofa
afterb = a; c = list(a)
then showing the new values ofa
,b
, andc
. Theis
betweena
andb
means that the value ofb
was also changed, but sincec
does not meet theis
test, its value is not changed.This is something I saw repeatedly at Stack Overflow: new Python programmers do not understand just when changing the value of one name will or will not change the value of another name. So understanding this consequence of the difference between
is
and==
is very practical. If you update this video, I recommend that you add showing the new values ofb
andc
at the end.