How to Check if a Variable Is None in Python (is None vs == None)

To check if a variable is None in Python, use the identity operator: if x is None:. To check that it is not None, use if x is not None:. Do not use == None or if not x for this: the first can be fooled by objects with a custom __eq__, and the second is also true for 0, "", [] and other empty values. This guide shows the difference with real output, plus None in functions, several variables, lists and pandas.

All examples were run with Python 3.12.5 and pandas 3.0.6 in the Windows Command Prompt. Reference: None in the Python docs and PEP 8 programming recommendations (“Comparisons to singletons like None should always be done with is or is not”).

is None and is not None

result = None

if result is None:
    print("no result yet")

result = 0
if result is not None:          # 0 is a real value, so this runs
    print("result is", result)

Output:

no result yet
result is 0

None is a single object, so is (which compares identity) is the exact and fastest test.

is None vs not x: falsy values

if not x is true for every falsy value, not just None. That is a common bug when 0 or an empty string is a valid value:

values = [None, 0, 0.0, "", [], {}, False, "0", [0]]

print(f"{'value':>8} | is None | not value")
for v in values:
    print(f"{v!r:>8} | {v is None!s:>7} | {not v!s:>9}")

Output:

   value | is None | not value
    None |    True |      True
       0 |   False |      True
     0.0 |   False |      True
      '' |   False |      True
      [] |   False |      True
      {} |   False |      True
   False |   False |      True
     '0' |   False |     False
     [0] |   False |     False
Command Prompt table comparing is None with not value for None, 0, 0.0, empty string, empty list, empty dict, False, the string '0' and a list containing 0
Only None is None; not value is True for all empty and zero values.

If you want to treat empty values and None the same way, if not x is fine. See check if a variable is null or empty in Python.

is None vs == None

class Anything:
    def __eq__(self, other):
        return True              # a (badly written) class that says it equals everything

x = Anything()
print("x == None:", x == None)   # True: == calls the object's __eq__
print("x is None:", x is None)   # False: is checks identity, it cannot be fooled

import numpy as np
arr = np.array([1, None, 3])
print("arr == None:", arr == None)   # element-wise, returns an array

Output:

x == None: True
x is None: False
arr == None: [False  True False]
Command Prompt output showing a class with a custom __eq__ making x == None True while x is None is False, and a NumPy array compared element-wise
== None asks the object; is None checks identity.

Linters such as flake8 flag == None as E711 for this reason.

isinstance and NoneType

You rarely need it, but type(None) is NoneType, which you can use with isinstance(), for example when checking several allowed types at once: isinstance(x, (int, type(None))).

values = [None, 0, "", "text"]

for v in values:
    print(f"{v!r:>7}: isinstance(v, type(None)) = {isinstance(v, type(None))}")

print(type(None))                    # <class 'NoneType'>
print(None is None, id(None) == id(None))   # there is only one None object

Output:

   None: isinstance(v, type(None)) = True
      0: isinstance(v, type(None)) = False
     '': isinstance(v, type(None)) = False
 'text': isinstance(v, type(None)) = False
<class 'NoneType'>
True True

None from functions and as a default argument

A function without a return statement returns None, which makes it a natural “not found” result. None is also the standard default for arguments that would otherwise be a mutable list or dict:

def find_user(user_id, users):
    for u in users:
        if u["id"] == user_id:
            return u
    # no return statement -> the function returns None

users = [{"id": 1, "name": "Anna"}, {"id": 2, "name": "Ben"}]

for uid in (2, 9):
    user = find_user(uid, users)
    if user is None:
        print(f"user {uid}: not found")
    else:
        print(f"user {uid}: {user['name']}")


def add_tag(tag, tags=None):         # None as a safe default for mutable arguments
    if tags is None:
        tags = []
    tags.append(tag)
    return tags

print(add_tag("a"), add_tag("b"))

Output:

user 2: Ben
user 9: not found
['a'] ['b']
Command Prompt output of a Python function returning None when a user is not found, checked with is None, and None used as a safe default argument
Checking a function’s None result.

Check several variables and lists

first, middle, last = "Ada", None, "Lovelace"

print("any None:", any(v is None for v in (first, middle, last)))
print("all set: ", all(v is not None for v in (first, middle, last)))

values = [4, None, 7, None, 1]
print("without None:", [v for v in values if v is not None])
print("None count:  ", values.count(None))

name = middle if middle is not None else "(none)"      # a default when None
print("middle name:", name)

Output:

any None: True
all set:  False
without None: [4, 7, 1]
None count:   2
middle name: (none)

None in pandas

pandas converts None in numeric data to NaN, so is None no longer finds it. Use isna() / notna():

import numpy as np
import pandas as pd

s = pd.Series([10, None, 30, np.nan])
print(s)
print("is None per value:", [v is None for v in s])       # pandas stored None as NaN
print("isna():", s.isna().tolist())                        # the right check in pandas

Output:

0    10.0
1     NaN
2    30.0
3     NaN
dtype: float64
is None per value: [False, False, False, False]
isna(): [False, True, False, True]
Command Prompt output of a pandas Series where None became NaN, is None returning False for every value and isna() finding the missing values
isna() catches both None and NaN.
GoalUse
Is it exactly None?x is None
Is it anything but None?x is not None
Is it None or empty/zero?not x
Missing values in pandas/NumPypd.isna(x), s.isna()
Default when Nonex if x is not None else default

Related Python checks:

Frequently asked questions

How do I check if a variable is None in Python?

Use if x is None:. For the opposite, use if x is not None:.

Should I use is None or == None?

Use is None. It checks identity and cannot be changed by a class’s __eq__; PEP 8 recommends it.

What is the difference between if not x and if x is None?

not x is true for None and for every falsy value (0, “”, [], {}, False). x is None is true only for None.

How do I check if a variable is not None?

if x is not None:. Avoid if not x is None; it works but is harder to read.

How do I check if several variables are None?

any(v is None for v in (a, b, c)) or all(v is not None for v in (a, b, c)).

Why does is None not work on a pandas column?

pandas stores missing values as NaN. Use s.isna() or pd.isna(value).