A lot of times when I'm doing if
s in Python, I find myself wondering whether to use is
or ==
for the check.
# do I do
if a is b:
...
# or
if a == b:
...
It can be a bit confusing if you're new to Python, and it's easy to assume the two can be used interchangeably. So, what's the difference?
is
The is
operator checks if both elements point to the same object. Let's fire up a python console to help illustrate this:
$ python3
Python 3.7.4
[Clang 10.0.1 (clang-1001.0.46.4)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> a = []
>>> b = []
>>> c = a
>>> a
[]
>>> b
[]
>>> c
[]
>>>
So, we've declared three variables and assigned them values. a
and b
are both empty lists, and c = a
. We can see that all three variables contain an empty list. Using is
to compare them:
>>> a is b
False
>>> b is c
False
>>> a is c
True
Despite the fact that a
and b
seem identical (in that they're both empty lists), the variables a
and b
do not point to the same object, therefore a is b
evaluates to False
. The same goes for b is c
.
Conversely, because we assigned the variable a
to c
, they both point to the same object, thus a is c
is True
.
==
==
on the other hand checks if both elements contain equal values. Whether or not they point to the same object doesn't matter here.
>>> a == b
True
>>> b == c
True
>>> a == c
True
All checks using ==
evaluate to True
, because the values of a
, b
and c
are all equal. If d = [1, 2, 3]
is introduced, a == d
, b == d
and c == d
would all be False
, because the values are not equal.
So if you want to check that elements point to the same object, use is
. If you're only interested in the equality of the values, use ==
.
Top comments (24)
Very nice, but a word of warning, identity (what
is
checks) is generally a language implementation detail, not something that should be relied upon.Consider:
That same example might not work precisely that way in another implementation of Python.
Mutable and immutable values behave very differently in terms of assignment and identity.
Except in some extremely rare, hack-y scenarios, you should only see
is
in the context ofis None
.Interesting. Thanks for the heads up.
You know, I wanted to mention something similar to this but didn't because we wouldn't usually do
if a is None
... a better way would beif not a
- so I didn't know exactly how to frame it.Well, no, you wouldn't want to do that.
if not a
is the accepted shorthand forif a == False
, butFalse
andNone
are distinct values. You should always explicitly test forNone
, although you can implicitly test for "not None":Awesome.
There's actually a bit more to it than that.
if not
checks "truthyness", not just equality to False. Sonot foo
will evaluate toTrue
iffoo
is any of these and more:False
None
0
[]
{}
""
The same thing applies in the other direction,
if [1]
will succeed because the list is not empty, empty list are "falsey" whereas lists containing elements are "truthy".The lesson here is pretty much don't use
if
without an explicit comparison (==
oris
) unless you're sure you know how truthy the value will be in all cases.There are some corner cases when you would like to use the full comparison form. For example if None is used as an "no argument value was passed" flag:
it will print message for calls foo(), foo(0), foo(""), foo([]).
Yes, it's always best to test for the presence of
None
explicitly, rather than implicitly.wouldn't 'is' be used in s scenario where we're comparing pointers like in a linked list?
while p is not q :
p = p.next
I think that is how 'is' should be used.
I've not used linked lists much so I wouldn't know but yeah, I guess that would work.
Well, Python doesn't have pointers, per se, nor would there ordinarily be a cause to implement your own linked list. It's virtually always best to use Python's own data structures, or at least build upon them.
yes.. but if you needed something fancy like a left leaning red black tree or a concurrent skip list you'd need 'is' to work for you for completeness.
(ps. I know they don't really have "pointers" but in these scenarios you use it like a pointer)
If you try to compare a variable with a literal using
is
oris not
you will get a syntax warning like this:I'm so happy to see a fellow Kenyan here.Thank you.
Isn't
a is b
essentially the same asid(a) == id(b)
?Haven't tried it out on a console, but it makes sense. I think it's the same.
Nice explanation, I used to compare if s in PHP , but this is interesting
So basically
checks to see if the variable is the same space in memory, while
checks to see if the value is identical?
That's how I understand it, yes.
Almost made a very very costly mistake with this.Thank you for the article.
Nice. I always enjoy reading your posts.
Thanks!
Nice and concise. Thanks.
Thank you so much.
You're welcome! π