ScreenshotNeo

BlogHow-to

How to Check if a List Is Empty in Python

Use Python truth testing: `if not items:` detects an empty list, while `if items:` detects a non-empty list.

By the ScreenshotNeo team1 October 20265 min read

For a normal Python list, use its truth value:

items = []

if not items:
    print("The list is empty")
else:
    print("The list has items")

Use if not items: for the empty case and if items: for the non-empty case. Empty sequences are false in Boolean contexts, and non-empty sequences are true according to Python’s truth-value rules. PEP 8 recommends this direct style for sequences.

1. The idiomatic empty-list check

This is the conventional form for branching when a list contains no elements:

def describe_items(items):
    if not items:
        return "The list is empty"
    return f"The list has {len(items)} item(s)"

print(describe_items([]))
print(describe_items(["red", "green"]))

not items becomes True when items is an empty list. For a non-empty list, it becomes False.

2. Checking for a non-empty list

When work should run only if there is at least one element, test the list directly:

queue = ["job-1", "job-2"]

if queue:
    job = queue.pop(0)
    print(f"Processing {job}")
else:
    print("There are no jobs")

This reads naturally and avoids an unnecessary length calculation or comparison.

3. Why direct truth testing works

Python allows any object in an if condition. An object is false when its __bool__() method returns False, or, when that method is absent, when its __len__() returns zero. The documentation lists empty sequences such as [] among false values.

The not operator reverses that value:

Expression Empty list Non-empty list
items False True
not items True False

4. None is different from an empty list

Both None and [] are false in a Boolean context, but they often mean different things. None can mean that no list was supplied, while [] means a list was supplied and currently has no elements.

def classify(items):
    if items is None:
        return "No list was provided"
    if not items:
        return "A list was provided, but it is empty"
    return "The list has items"

print(classify(None))
print(classify([]))
print(classify([42]))

Check items is None first when the distinction matters. Do not write if not items when you need to tell these two states apart.

5. When to use len(items) == 0

len(items) == 0 is correct and explicit:

items = []

if len(items) == 0:
    print("The count is exactly zero")

Prefer it when the numeric count is part of the explanation or condition:

if len(errors) == 0:
    report_status("No errors found")
elif len(errors) > 10:
    report_status("More than ten errors found")

For an ordinary empty-versus-non-empty branch, PEP 8’s recommended forms are if not seq: and if seq:. It specifically contrasts them with if len(seq): and if not len(seq):.

6. Forms to avoid

Do not use is []

items = []

# Wrong: tests object identity, not whether the list has elements
if items is []:
    print("This is not a reliable emptiness test")

is asks whether two references point to the same object. The literal [] creates another list, so this identity comparison is normally false even when items is empty.

Do not use if len(items): as the default style

# Less clear for a simple presence check
if len(items):
    process(items)

# Preferred
if items:
    process(items)

items == [] can work, but is narrower

Equality comparison works when you specifically want to compare with an empty list:

if items == []:
    print("Equal to an empty list")

Truth testing is usually better because it expresses the intent and also works for other sequence types such as tuples and strings.

7. Lists, other sequences, and custom objects

The same pattern applies to tuples, strings, sets, dictionaries, and other collections with normal truth-value behavior:

values = ()
name = ""
flags = set()
settings = {}

if not values:
    print("The tuple is empty")
if not name:
    print("The string is empty")
if not flags:
    print("The set is empty")
if not settings:
    print("The dictionary is empty")

For custom classes, truth testing may call a user-defined __bool__() or __len__(). Follow the class’s documented meaning rather than assuming every object behaves like a list.

8. Common mistakes and fixes

Problem Cause Fix
An empty list enters the non-empty branch The condition was inverted Use if items: only for work that requires elements; use if not items: for the empty case.
None and [] are treated identically Both are false in Boolean contexts Check items is None before not items.
is [] never matches is checks identity Use if not items: or, when equality is intended, items == [].
len() raises an exception The value is None or is not sized Validate the value first, or define the function parameter as a list and reject invalid input clearly.
A generator appears empty but cannot be checked repeatedly Generators are iterators, not lists; checking requires consuming values Materialize it with list(generator) when appropriate, or process it in one pass.

9. Performance and reliability notes

  • For built-in lists, truth testing is constant-time and does not scan every element.
  • len(items) == 0 is also constant-time for built-in lists; choose it for clarity when a count is part of the rule.
  • Neither form copies the list.
  • Do not call an expensive function repeatedly just to test its result. Store the result once, then test it.
items = load_items_once()
if not items:
    handle_empty()
else:
    handle_items(items)

10. Practical examples

Validating input

def require_tags(tags):
    if tags is None:
        raise ValueError("tags must be provided")
    if not tags:
        raise ValueError("tags must contain at least one value")
    return tags

Building a result only when matches exist

matches = [user for user in users if user.active]
if matches:
    send_notifications(matches)
else:
    log("No active users")

Using a list default safely

def add_item(item, items=None):
    if items is None:
        items = []
    items.append(item)
    return items

Using None as the default avoids sharing one mutable list between function calls.

11. Or skip the browser setup

If your workflow also needs screenshots of pages or reports, ScreenshotNeo provides a website screenshot API. One request returns a PNG, JPEG, WebP, or PDF. The equivalent of a direct, no-browser setup is:

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp

Python:

import requests

r = requests.get(
    "https://api.screenshotneo.com/v1/shot",
    params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"},
    timeout=90,
)
open("shot.webp", "wb").write(r.content)

Node.js:

const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);

See the ScreenshotNeo API documentation for request options. Cookie banners, newsletter popups, and chat widgets are removed before the shot. Bot checks, blank pages, failed loads, timeouts, and cache hits are not billed, and response headers identify the page verdict and billing status. An MCP server lets AI agents take screenshots, inspect pages, and capture PDFs. The free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 shots.

Create a free ScreenshotNeo account.

12. FAQ

Is if not my_list safe when the list is empty?

Yes. It is the standard Python check for an empty list.

Should I use len(my_list) == 0 or not my_list?

Use not my_list for a normal empty branch. Use len(my_list) == 0 when the explicit count improves the surrounding logic.

How do I check that a list has at least one item?

Use if my_list:.

Can I check a list without changing it?

Yes. Truth testing and len() do not modify the list.

What if the variable might not be a list?

Validate its type or interface at the boundary, then use the appropriate truth-value rule for the accepted type.