994

I've always thought of the if not x is None version to be more clear, but Google's style guide and PEP-8 both use if x is not None. Are there any minor performance differences (I'm assuming not), and is there any case where one really doesn't fit (making the other a clear winner for my convention)?*

*I'm referring to any singleton, rather than just None.

...to compare singletons like None. Use is or is not.

General Grievance
  • 4,555
  • 31
  • 31
  • 45
orokusaki
  • 55,146
  • 59
  • 179
  • 257
  • 46
    `is not` is an operator in it's own right. Like `!=`. If you prefer `not x is None` then your should also prefer `not a == b` over `a != b`. – Tomasz Gandor Mar 14 '18 at 10:12
  • @TomaszGandor I no longer have this opinion about `not x is None` (the answers here convinced me) - it is, however, worth noting that `not a == b` is the preferred style in Python, compared to `a != b`. – orokusaki Mar 14 '18 at 14:20
  • 14
    @orokusaki is `not a == b` really the preferred style? I have never seen it done that way and everywhere I look people all use `!=`. – Mike - SMT Dec 07 '18 at 15:56
  • 7
    @orokusaki In Python readability counts so it is a preferred style to use one operator `!=` instead of two operators `not`, `==`. – Jeyekomon Jan 21 '19 at 15:54

9 Answers9

1271

There's no performance difference, as they compile to the same bytecode:

>>> import dis
>>> dis.dis("not x is None")
  1           0 LOAD_NAME                0 (x)
              2 LOAD_CONST               0 (None)
              4 COMPARE_OP               9 (is not)
              6 RETURN_VALUE
>>> dis.dis("x is not None")
  1           0 LOAD_NAME                0 (x)
              2 LOAD_CONST               0 (None)
              4 COMPARE_OP               9 (is not)
              6 RETURN_VALUE

Stylistically, I try to avoid not x is y, a human reader might misunderstand it as (not x) is y. If I write x is not y then there is no ambiguity.

Boris Verkhovskiy
  • 14,854
  • 11
  • 100
  • 103
Daniel Stutzbach
  • 74,198
  • 17
  • 88
  • 77
  • 164
    Unless the same human reader thought it was `x is (not y)`. But I tend to agree with you for your other reasoning. – Etaoin Apr 26 '10 at 05:52
  • 33
    additionally "is not" is less ambiguous in this context "if a is not None and b is None:" vs "if not a is None and b is None:" – Gordon Wrigley Apr 28 '11 at 01:19
  • 226
    the operator should be "aint" – bean Apr 05 '19 at 16:20
  • 3
    or "unless" (`if not x is None` -> `unless x is None`) – musava_ribica Nov 19 '20 at 15:13
  • In the end `x != None` is the clearest syntax, no need to invent the octagonal wheel. – mins Mar 23 '21 at 10:30
  • 9
    I think exactly the opposite is true. The first time I saw `x is not y` I thought the programmer was comparing x to "not y". – Jim Newton Jun 21 '21 at 12:18
  • 1
    @mins while that's true, `==` doesn't check the exact same thing as `is`. For example, `[1, 2, 3] == [1, 2, 3]` is true, but `[1, 2, 3] is [1, 2, 3]` is false. (same value vs. "are they the exact same object") – jemand771 Jul 08 '21 at 08:08
  • 1
    @jemand771: Correct, I'd say checking `x is None` (x is the object which value is None) is mentally wrong, as we don't care (and don't know) if `None` constant is represented by one or multiple objects, we are interested in the value only and `x == None` (x value is equal to None value) is the correct translation of what we want to do. Same for other built-in singletons, `True`, etc. This confusion doesn't exist in common languages, but in python there is no actual constants, at best singletons, a questionable choice according to pythonic verses (explicit is better than implicit). – mins Jul 08 '21 at 10:22
  • 1
    Having two syntax options goes against one of the Zen of Python principles: "There should be one– and preferably only one –obvious way to do it". Having a space in the operator `is not` is confusing. It should be either `isnot` or `aint` – Jonathan Livni Aug 18 '22 at 18:53
406

Both Google and Python's style guide is the best practice:

if x is not None:
    # Do something about x

Using not x can cause unwanted results.

See below:

>>> x = 1
>>> not x
False
>>> x = [1]
>>> not x
False
>>> x = 0
>>> not x
True
>>> x = [0]         # You don't want to fall in this one.
>>> not x
False

You may be interested to see what literals are evaluated to True or False in Python:


Edit for comment below:

I just did some more testing. not x is None doesn't negate x first and then compared to None. In fact, it seems the is operator has a higher precedence when used that way:

>>> x
[0]
>>> not x is None
True
>>> not (x is None)
True
>>> (not x) is None
False

Therefore, not x is None is just, in my honest opinion, best avoided.


More edit:

I just did more testing and can confirm that bukzor's comment is correct. (At least, I wasn't able to prove it otherwise.)

This means if x is not None has the exact result as if not x is None. I stand corrected. Thanks bukzor.

However, my answer still stands: Use the conventional if x is not None. :]

Arsen Khachaturyan
  • 7,904
  • 4
  • 42
  • 42
Xavier Ho
  • 17,011
  • 9
  • 48
  • 52
141

Code should be written to be understandable to the programmer first, and the compiler or interpreter second. The "is not" construct resembles English more closely than "not is".

Mark Ransom
  • 299,747
  • 42
  • 398
  • 622
  • 3
    "*Code should be written to be understandable to the programmer first*": That was the principle used to design COBOL, a language from non academics, which received much [condescension from academics](http://www.cs.umd.edu/~ben/papers/Schneiderman1985Relationship.pdf), some being legitimate, most not. As for the reasons... "*For a computer scientist to write sympathetically about COBOL is an act bordering on heresy. It requires courage because academic colleagues and data processing professionals are both likely to be suspicious of my motives.*" – mins Jul 08 '21 at 13:19
42

Python if x is not None or if not x is None?

TLDR: The bytecode compiler parses them both to x is not None - so for readability's sake, use if x is not None.

Readability

We use Python because we value things like human readability, useability, and correctness of various paradigms of programming over performance.

Python optimizes for readability, especially in this context.

Parsing and Compiling the Bytecode

The not binds more weakly than is, so there is no logical difference here. See the documentation:

The operators is and is not test for object identity: x is y is true if and only if x and y are the same object. x is not y yields the inverse truth value.

The is not is specifically provided for in the Python grammar as a readability improvement for the language:

comp_op: '<'|'>'|'=='|'>='|'<='|'<>'|'!='|'in'|'not' 'in'|'is'|'is' 'not'

And so it is a unitary element of the grammar as well.

Of course, it is not parsed the same:

>>> import ast
>>> ast.dump(ast.parse('x is not None').body[0].value)
"Compare(left=Name(id='x', ctx=Load()), ops=[IsNot()], comparators=[Name(id='None', ctx=Load())])"
>>> ast.dump(ast.parse('not x is None').body[0].value)
"UnaryOp(op=Not(), operand=Compare(left=Name(id='x', ctx=Load()), ops=[Is()], comparators=[Name(id='None', ctx=Load())]))"

But then the byte compiler will actually translate the not ... is to is not:

>>> import dis
>>> dis.dis(lambda x, y: x is not y)
  1           0 LOAD_FAST                0 (x)
              3 LOAD_FAST                1 (y)
              6 COMPARE_OP               9 (is not)
              9 RETURN_VALUE
>>> dis.dis(lambda x, y: not x is y)
  1           0 LOAD_FAST                0 (x)
              3 LOAD_FAST                1 (y)
              6 COMPARE_OP               9 (is not)
              9 RETURN_VALUE

So for the sake of readability and using the language as it was intended, please use is not.

To not use it is not wise.

Russia Must Remove Putin
  • 374,368
  • 89
  • 403
  • 331
  • "The `not` binds more weakly than `is`, so there is no logical difference here" -- except that Python does not have to enforce logical and algebraic identities to hold (no intrinsic reason for `(1 + 2)*3` to evaluate the same as `1*3 + 2*3`). Here apparently Python is cheating and optimising `UNARY_NOT` away. – Alexey Feb 21 '19 at 11:27
33

The answer is simpler than people are making it.

There's no technical advantage either way, and "x is not y" is what everybody else uses, which makes it the clear winner. It doesn't matter that it "looks more like English" or not; everyone uses it, which means every user of Python--even Chinese users, whose language Python looks nothing like--will understand it at a glance, where the slightly less common syntax will take a couple extra brain cycles to parse.

Don't be different just for the sake of being different, at least in this field.

Glenn Maynard
  • 55,829
  • 10
  • 121
  • 131
18

Personally, I use

if not (x is None):

which is understood immediately without ambiguity by every programmer, even those not expert in the Python syntax.

MikeTeX
  • 529
  • 4
  • 18
  • 8
    A fair argument that I agree with, but I believe the argument of following idiomatic style is stronger. – clacke Oct 07 '16 at 09:02
  • 1
    +1 To most non-python programmers `if x is not None` sounds like `if x is (not None)` which is most likely a coding error. On the other hand to most python programmers `if not (x is None)` sounds like you have no experience with the language. – Robert Jul 17 '20 at 13:15
11

The is not operator is preferred over negating the result of is for stylistic reasons. "if x is not None:" reads just like English, but "if not x is None:" requires understanding of the operator precedence and does not read like english.

If there is a performance difference my money is on is not, but this almost certainly isn't the motivation for the decision to prefer that technique. It would obviously be implementation-dependent. Since is isn't overridable, it should be easy to optimise out any distinction anyhow.

Mike Graham
  • 73,987
  • 14
  • 101
  • 130
4

if not x is None is more similar to other programming languages, but if x is not None definitely sounds more clear (and is more grammatically correct in English) to me.

That said it seems like it's more of a preference thing to me.

Davy8
  • 30,868
  • 25
  • 115
  • 173
2

I would prefer the more readable form x is not y than I would think how to eventually write the code handling precedence of the operators in order to produce much more readable code.

stefanogreg
  • 121
  • 1
  • 8