946

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?

2
  • 3
    How about if val: ? Commented Nov 6, 2020 at 2:18
  • 23
    That is not the same test! That if will be false if val is 0, "", [], 0.0. etc. as well as if it is None. Commented Nov 8, 2020 at 11:46

4 Answers 4

1361
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.

Sign up to request clarification or add additional context in comments.

10 Comments

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.
"not None" returns True. Interesting.
@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 val = ''; print(val is not None) prints True, so what part do you find incorrect?
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.
|
149

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.

Comments

40

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.

2 Comments

What is the difference betwen compare_op 9 and 3?
@evolvedmicrobe From the dis doc (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 !=.
25

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

1 Comment

That's rather dastardly __eq__() behavior, and something I hadn't considered. Good answer for catching a corner case.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.