Python if not == vs if != Python if not == vs if != python python

Python if not == vs if !=


Using dis to look at the bytecode generated for the two versions:

not ==

  4           0 LOAD_FAST                0 (foo)              3 LOAD_FAST                1 (bar)              6 COMPARE_OP               2 (==)              9 UNARY_NOT                        10 RETURN_VALUE   

!=

  4           0 LOAD_FAST                0 (foo)              3 LOAD_FAST                1 (bar)              6 COMPARE_OP               3 (!=)              9 RETURN_VALUE   

The latter has fewer operations, and is therefore likely to be slightly more efficient.


It was pointed out in the commments (thanks, @Quincunx) that where you have if foo != bar vs. if not foo == bar the number of operations is exactly the same, it's just that the COMPARE_OP changes and POP_JUMP_IF_TRUE switches to POP_JUMP_IF_FALSE:

not ==:

  2           0 LOAD_FAST                0 (foo)              3 LOAD_FAST                1 (bar)              6 COMPARE_OP               2 (==)              9 POP_JUMP_IF_TRUE        16

!=

  2           0 LOAD_FAST                0 (foo)              3 LOAD_FAST                1 (bar)              6 COMPARE_OP               3 (!=)              9 POP_JUMP_IF_FALSE       16

In this case, unless there was a difference in the amount of work required for each comparison, it's unlikely you'd see any performance difference at all.


However, note that the two versions won't always be logically identical, as it will depend on the implementations of __eq__ and __ne__ for the objects in question. Per the data model documentation:

There are no implied relationships among the comparison operators. The truth of x==y does not imply that x!=y is false.

For example:

>>> class Dummy(object):    def __eq__(self, other):        return True    def __ne__(self, other):        return True>>> not Dummy() == Dummy()False>>> Dummy() != Dummy()True

Finally, and perhaps most importantly: in general, where the two are logically identical, x != y is much more readable than not x == y.


@jonrsharpe has an excellent explanation of what's going on. I thought I'd just show the difference in time when running each of the 3 options 10,000,000 times (enough for a slight difference to show).

Code used:

def a(x):    if x != 'val':        passdef b(x):    if not x == 'val':        passdef c(x):    if x == 'val':        pass    else:        passx = 1for i in range(10000000):    a(x)    b(x)    c(x)

And the cProfile profiler results:

enter image description here

So we can see that there is a very minute difference of ~0.7% between if not x == 'val': and if x != 'val':. Of these, if x != 'val': is the fastest.

However, most surprisingly, we can see that

if x == 'val':        pass    else:

is in fact the fastest, and beats if x != 'val': by ~0.3%. This isn't very readable, but I guess if you wanted a negligible performance improvement, one could go down this route.


In the first one, Python has to execute one more operation than necessary (instead of just checking not equal to, it has to check if it is not true that it is equal, thus one more operation). It would be impossible to tell the difference from one execution, but if run many times, the second would be more efficient. Overall I would use the second one, but mathematically they are the same