525

I recently came across this syntax, I am unaware of the difference.

I would appreciate it if someone could tell me the difference.

wjandrea
  • 28,235
  • 9
  • 60
  • 81
Mahdi Yusuf
  • 19,931
  • 26
  • 72
  • 101
  • 7
    See [Is there a difference between `==` and `is` in python?](http://stackoverflow.com/questions/132988/is-there-a-difference-between-and-is-in-python/134659#134659) – Matthew Flaschen Jul 15 '10 at 16:58
  • 2
    Does this answer your question? [Is there a difference between "==" and "is"?](https://stackoverflow.com/questions/132988/is-there-a-difference-between-and-is) – user Jan 20 '20 at 17:30
  • It's unclear if this question is about `is` vs `==`, or about the nature of what exactly `None` is and how the behaviour differs in either context (the latter is why I ended up here). Based on the vagueness and lack of OP responses... I'm surprised this has so many upvotes. I mean... cmon... the question is not even written in the actual question... – RTbecard Jan 22 '20 at 18:42

5 Answers5

472

The answer is explained here.

To quote:

A class is free to implement comparison any way it chooses, and it can choose to make comparison against None mean something (which actually makes sense; if someone told you to implement the None object from scratch, how else would you get it to compare True against itself?).

Practically-speaking, there is not much difference since custom comparison operators are rare. But you should use is None as a general rule.

Ben Hoffstein
  • 102,129
  • 8
  • 104
  • 120
  • That was an interesting (and short) read. And some useful information into the `is` v. `==`. – Wayne Werner Jul 15 '10 at 16:59
  • 129
    Also, `is None` is a bit (~50%) faster than `== None` :) – Nas Banov Jul 16 '10 at 01:08
  • 43
    @myusuf3: >>> timeit.Timer('None is None').timeit() | 0.225 | >>> timeit.Timer('None == None').timeit() | 0.328 – Nas Banov Jan 25 '12 at 21:44
  • 16
    @myusuf3 You don't really need a proof for that. `is` is, basically, integer comparison while `==` is not only resolving references but comparing values which may have mismatching types. – Pijusn Aug 09 '13 at 15:40
  • 2
    Personally, I feel that `==` should be used in all cases except when either speed matters or you really need to know if you are referring to the same object. `==` is much simpler and easier to understand. It doesn't leave the reader wondering "why did he use `is` instead of `==`". – Tim Ludwinski Apr 10 '14 at 18:40
  • 5
    One on favour of "is". When a variable can be either None or something that has no meaningful comparison with None. For example, a variable can be a numpy.array or None (my particular case). – Jblasco Oct 14 '14 at 10:38
  • 6
    I would like to add to what @TimLudwinski is saying: first, if someone chose to override the equality operator to make None a special case, why would we want to tell them otherwise? Second, "There should be one-- and preferably only one --obvious way to do it." And the obvious way to check if something is equal to something is, well, the equality operator. – Yuval Dec 14 '15 at 16:45
  • Personally, I find the == None and != None much easier to read than 'is None' and 'is not None' -- it's simply more concise. Imagine in Java, if you had to type in " is not null " in place of " != null" and " is null" in place of " == null"! I would imagine that would get very annoying, very quickly! – Gino May 01 '17 at 12:01
  • 5
    The truth is we all do it because of the SQL NULL trauma. – MK. Sep 06 '17 at 17:36
  • 4
    Numpy uses custom comparison operators and will perform element-wise comparisons for array == True/False, and at some point in the future will do the same for None. "If array == False:" does not work. In the future "if array == None:" won't work either. Custom operators cannot be ignored. – Matt Thompson Mar 29 '18 at 01:35
  • @Matt Thompson: For Numpy, using "if array is None" still works, though. "Is" checks whether the entire object is None instead of doing element-wise comparison. – Andrew Jan 10 '20 at 15:03
  • I used to be a hardcore supporter of "use `is None` unless you have a good reason to do `== None`", but it was precisely the "what if someone wants to implement a `None`-like object" case which made me start wondering if actually maybe `== None` is The Right Way(tm)... – mtraceur Feb 26 '21 at 21:38
  • You know those hard-to-track-down errors when a line like `foo.bar` throws a `TypeError: NoneType has no attribute "bar"` and you're left having to step backwards through the logic and figure out where the `None` that ended up assigned to `foo` could have come from. I thought the other day that a magic `None` object which isn't a singleton but instead carries annotations about where it came from would help that, but that would break `is None` checks. Basically, when we say `is None`, we're marrying ourselves to the language implementation/design choice that `None` is a singleton. – mtraceur Feb 26 '21 at 21:44
226
class Foo:
    def __eq__(self,other):
        return True
foo=Foo()

print(foo==None)
# True

print(foo is None)
# False
unutbu
  • 842,883
  • 184
  • 1,785
  • 1,677
69

In this case, they are the same. None is a singleton object (there only ever exists one None).

is checks to see if the object is the same object, while == just checks if they are equivalent.

For example:

p = [1]
q = [1]
p is q # False because they are not the same actual object
p == q # True because they are equivalent

But since there is only one None, they will always be the same, and is will return True.

p = None
q = None
p is q # True because they are both pointing to the same "None"
Donald Miner
  • 38,889
  • 8
  • 95
  • 118
  • 21
    This answer is not correct, as explained in Ben Hoffstein's answer below http://stackoverflow.com/questions/3257919/is-none-vs-none/3257957#3257957. `x == None` may evaluate to `True` even if `x` is not `None` but an instance of some class with its own custom equality operator. – max Nov 16 '10 at 03:00
55

It depends on what you are comparing to None. Some classes have custom comparison methods that treat == None differently from is None.

In particular the output of a == None does not even have to be boolean !! - a frequent cause of bugs.

For a specific example take a numpy array where the == comparison is implemented elementwise:

import numpy as np
a = np.zeros(3) # now a is array([0., 0., 0.])
a == None #compares elementwise, outputs array([False, False, False]), i.e. not boolean!!!
a is None #compares object to object, outputs False
PGlivi
  • 996
  • 9
  • 12
  • 9
    I think this is a better answer than the current accepted answer, as it has easy to understand examples. – Olsgaard Aug 06 '20 at 07:56
6

If you use numpy,

if np.zeros(3)==None: pass

will give you error when numpy does elementwise comparison

jf328
  • 6,841
  • 10
  • 58
  • 82