Explain Codes LogoExplain Codes Logo

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

python
best-practices
readability
performance
Nikita BarsukovbyNikita BarsukovΒ·Oct 13, 2024
⚑TLDR

Use if x is not None:. This construct is a clear-cut and precise way to explicitly check that x is not None, and avoids confusion with checks for other false or empty values like False, 0, or empty collections.

Here's an example:

if x is not None: # "We're about to start the party because X is not None! πŸŽ‰"

This construct mirrors natural spoken English, enhancing readability and intuitiveness.

Performance: A draw

Contrary to what intuition might suggest, there's no performance difference between if x is not None and if not x is None. Both expressions compile to the same bytecode, so you won't get any extra speed or slowed down by picking one over the other.

The role of readability and conventions

While both forms are syntactically correct, favor readability and maintainability by following Python's coding conventions as laid out in PEP 8. This official Python style guide promotes the if x is not None: format, making it easier on developers to understand your intention.

Emulating natural language

How the condition reads as natural language can provide insight into code readability. "X is not None" follows a straightforward declarative pattern, while "not X is None" could be misinterpreted as a negation of "X is None" which requires an extra cognitive step to decipher.

Working with Python grammar

In Python, is not is a binary operator and part of Python's grammar. Abiding by the guidance of the grammar reinforces using if x is not None:, making your code more idiomatic.

Context matters

While if x is not None: is the default practice, be context-aware. Different scenarios might require different expressions, but when checking for None, this construct typically suits well.

Use-cases in action

Let's look at three examples where if x is not None: can be specifically beneficial:

Default arguments in functions:

def func(arg=None): if arg is not None: # "Hey, got an arg? Let's party! πŸŽ‰"

Here, the check ensures the function behaves correctly even when arg is falsy but not None.

Optional dictionary keys:

settings = {'theme': None} if settings.get('theme') is not None: # "Got a theme? Time to set the mood! πŸŒ†"

A deliberate key set to None is not acted upon.

Conditional code execution:

result = expensive_computation() if result is not None: # "We've got gold! Eureka! πŸ’°"

In this case, dividing the "no result" (None) from other falsy values is crucial for deciding the program's execution flow.