3

The previous dev has left a really strange not x is None yoda condition in the code:

>>> x = None
>>> not x is None
False
>>> x = 1
>>> not x is None
True

After some testing, I seem the same output as x is not None.

>>> x = None
>>> not x is None
False
>>> x is not None
False
>>> x = 1
>>> not x is None
True
>>> x is not None
True

Is not x is None always equivalent to x is not None?

To break down the condition, is it not (x is None) or (not x) is None? Or will the former always be equivalent to the latter?

alvas
  • 115,346
  • 109
  • 446
  • 738
  • It's all about the operator precedence. Read this answer http://stackoverflow.com/questions/31421379/why-does-nottrue-in-false-true-return-false/31458009#31458009 – Mazdak Apr 17 '17 at 08:50
  • Yup according to the [document](https://docs.python.org/3/reference/expressions.html#operator-precedence), **not** has lower precedence than comparison **is**. So your former assumption should be correct. – umutto Apr 17 '17 at 08:53
  • A “Yoda condition” would be `None is x`. – Ry- Apr 17 '17 at 09:21

2 Answers2

3

Since is has higher precendence than not, then the expressions are equivalent:

In case x = None: x is None evaluates to True, and not x is None evaluates to False In case x = 1: x is None evaluates to False, and not x is None evaluates to True

In case x = None: x is not None evaluates to False In case x = 1: x is not None evaluates to True.

Therefore, even though the actions are not syntactically equivalent, the results are equivalent.

This is the AST of not x is None:

enter image description here

This is the AST of x is not None:

enter image description here

As can be seen in the second diagram, the inner node is the compare node, and therefore x is None is evaluated before the not.

Regarding actual evaluation of the expression, it seems that python creates the same bytecode for both. It can be seen in this example:

def foo(x):
    x is not None


def bar(x):
    not x is None

import dis
dis.dis(foo)
dis.dis(bar)

As both generate:

      0 LOAD_FAST                0 (x)
      3 LOAD_CONST               0 (None)
      6 COMPARE_OP               9 (is not)
      9 POP_TOP             
     10 LOAD_CONST               0 (None)
     13 RETURN_VALUE 
Elisha
  • 23,310
  • 6
  • 60
  • 75
1

is not is (I believe, the only) two-keyword operator in Python, and x is not y is entirely equivalent to not x is y. The same result will also be returned by id(x) != id(y). The canonical spelling for best reader comprehension would be x is not y.

holdenweb
  • 33,305
  • 7
  • 57
  • 77