907

Out of these not None tests.

if val != None:

if not (val is None):

if val is not None:

Which one is preferable, and why?

lospejos
  • 1,976
  • 3
  • 19
  • 35
prosseek
  • 182,215
  • 215
  • 566
  • 871

4 Answers4

1300
if val is not None:
    # ...

is the Pythonic idiom for testing that a variable is not set to None. This idiom has particular uses in the case of declaring keyword functions with default parameters. is tests identity in Python. Because there is one and only one instance of None present in a running Python script/program, is is the optimal test for this. As Johnsyweb points out, this is discussed in PEP 8 under "Programming Recommendations".

As for why this is preferred to

if not (val is None):
    # ...

this is simply part of the Zen of Python: "Readability counts." Good Python is often close to good pseudocode.

Community
  • 1
  • 1
gotgenes
  • 38,661
  • 28
  • 100
  • 128
  • 73
    also, "is not" has special semeantics created for this purpose (it's not a logical consequence of how expressions are constructed; "1 is (not None)" and "1 is not None" have two different outcomes. – Ivo van der Wijk Mar 26 '12 at 11:03
  • 3
    "not None" returns True. Interesting. – Ries Jun 14 '13 at 13:18
  • @gotgenes Not always right. Eg: var = ''. If you run this code, it tests successfully for None. Hence, you are not able to test if the variable was set to None or an empty string. – Ethan Aug 30 '13 at 01:02
  • 3
    @Ethan `val = ''; print(val is not None)` prints `True`, so what part do you find incorrect? – gotgenes Aug 30 '13 at 15:46
  • @gotgenes My intent was testing a variable if it's set explicitly to `None`. I want to differentiate between empty string and None. Eg use case: a routine initializing `val = None` and caller sends `''`. – Ethan Sep 06 '13 at 14:35
  • Right, because "is not None" *is far more readable* that not (val is None). Clearly it means that something is the opposite of nothing, as oppose to the inverse of something as nothing. Much better. Thanks! – Erik Aronesty Jul 08 '15 at 19:29
  • 2
    As for why the ``val != None`` is not recommended: If ``val`` can be either ``None`` or a more complex thing, like a numpy array, it's not entirely clear whether this intends to be an element-wise comparison (e.g: ``arr>0 `` will produce a list of indices at which elements of arr are positive), so if you expect ``val`` to be either an array or ``None``, then ``arr is None`` is the safest way to test this. In fact, Python 2.7.6 generates a warning that ``arr != None`` will work element-wise in the future. ``arr is not None`` is also nicer to read. – Zak Dec 12 '16 at 15:29
  • "Because there is one and only one instance of `None` present in a running Python script/program, `is` is the optimal test for this". Does this make the case for `val is 0` or `val is 'a'`? – nivk Nov 28 '18 at 03:44
  • @nivk good question. Small integers and short strings are interned, so that would work. The problem is that it is value-dependent: `val = 'asdasdasgerefgereasdasdasidonefe fkefe'; val is 'asdasdasgerefgereasdasdasidonefe fkefe'` is False even though both strings are identical. More generally, the internment of the strings is implementation-dependent and depends on how the strings were defined: see `val = '50'` vs `val = str(50)` – Davidmh Oct 20 '20 at 07:55
  • Since no one has mentioned it. It's worth noting that `not` is case sensitive and hence `is Not != is not`. – Abu Taha Oct 18 '22 at 18:39
143

From, Programming Recommendations, PEP 8:

Comparisons to singletons like None should always be done with is or is not, never the equality operators.

Also, beware of writing if x when you really mean if x is not None — e.g. when testing whether a variable or argument that defaults to None was set to some other value. The other value might have a type (such as a container) that could be false in a boolean context!

PEP 8 is essential reading for any Python programmer.

Community
  • 1
  • 1
johnsyweb
  • 136,902
  • 23
  • 188
  • 247
38

The best bet with these types of questions is to see exactly what python does. The dis module is incredibly informative:

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

Notice that the last two cases reduce to the same sequence of operations, Python reads not (val is None) and uses the is not operator. The first uses the != operator when comparing with None.

As pointed out by other answers, using != when comparing with None is a bad idea.

Boris Verkhovskiy
  • 14,854
  • 11
  • 100
  • 103
SheetJS
  • 22,470
  • 12
  • 65
  • 75
  • 1
    What is the difference betwen compare_op 9 and 3? – evolvedmicrobe Jan 10 '17 at 01:01
  • 3
    @evolvedmicrobe From the `dis doc` ([https://docs.python.org/3/library/dis.html](https://docs.python.org/3/library/dis.html)), `COMPARE_OP` performs the boolean operation corresponding to the tuple `dis.cmp_op = ('<', '<=', '==', '!=', '>', '>=', 'in', 'not in', 'is', 'is not', 'exception match', 'BAD')`. So `COMPARE_OP 9` performs `is not` and `COMPARE_OP 3` performs `!=`. – nivk Nov 20 '18 at 18:55
25

Either of the latter two, since val could potentially be of a type that defines __eq__() to return true when passed None.

Ignacio Vazquez-Abrams
  • 776,304
  • 153
  • 1,341
  • 1,358
  • 4
    That's rather dastardly `__eq__()` behavior, and something I hadn't considered. Good answer for catching a corner case. – gotgenes Oct 19 '10 at 03:37