Crashes, No Sound, or Screen Glitches?
Random freezes, missing sound and display glitches usually trace back to one bad driver. Find and replace yours safely.Free scan · under a minuteWindows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallUse Python’s truth-value test: if not items: runs when items is an empty list, while if items: runs when it contains one or more elements.
items = []
if not items:
print("The list is empty")
else:
print("The list has items")
This is the conventional Python style recommended by PEP 8. Use len(items) == 0 when the numeric count is itself part of the logic, and check None separately when “not supplied” differs from “supplied but empty.”
Why if not items detects an empty list
Python allows any object in an if condition. It asks the object for its truth value. An object is false when its __bool__() method returns False or, when that method is absent, its __len__() method returns zero. The built-in false values include empty sequences such as [].
The not operator reverses that result. An empty list is false, so not items becomes True. A non-empty list is true, so not items becomes False.
Do these 3 things before closing this tab:
1Scan for outdated or missing drivers - takes under a minute2Repair Windows errors before they cause bigger problems3Fix the driver behind crashes, sound loss and screen glitches#1 Best Overall
def describe(items):
if not items:
return "empty"
return "contains items"
print(describe([])) # empty
print(describe(["red"])) # contains items
The test checks the number of elements, not whether the elements themselves are truthy. A list containing 0, False, None, or an empty string is still non-empty:
values = [False]
if values:
print("There is one element") # This branch runs
Checking both empty and non-empty cases
Use the positive form when the main path needs at least one element:
queue = ["job-17", "job-18"]
if queue:
first_job = queue.pop(0)
print(f"Processing {first_job}")
else:
print("Nothing is queued")
This avoids indexing an empty list. Code such as queue[0] raises IndexError when no element exists, so guard the access with if queue: or handle the exception when that is the intended design.
When len(items) == 0 is the better expression
len(items) == 0 is correct for a list and makes the count explicit:
items = load_items()
if len(items) == 0:
print("No items were returned")
elif len(items) == 1:
print("Exactly one item was returned")
else:
print(f"{len(items)} items were returned")
Use this form when the program is reasoning about a number, such as distinguishing zero, one, and many. If the only question is whether a sequence has anything in it, PEP 8 prefers if items: and if not items: over if len(items): and if not len(items):.
For a built-in list, both approaches are constant-time operations: obtaining its length does not scan every element. The difference is primarily readability and the fact that direct truth testing also communicates that the code accepts any sequence-like value with normal truth semantics.
Do not confuse None with an empty list
None and [] are both false in a Boolean context, but they often mean different things. None commonly means that no value was provided, while an empty list means a value was provided and contains zero elements.
Rank #2
def report(items):
if items is None:
print("No list was provided")
elif not items:
print("A list was provided, but it is empty")
else:
print(f"The list has {len(items)} items")
report(None)
report([])
report(["ready"])
Use is None for the absence check. Identity checks are the idiomatic way to test for the singleton None; an equality comparison can be overloaded by custom objects.
If absence and emptiness have the same meaning in your function, you can deliberately normalize them:
def count_items(items=None):
return len(items or [])
Only use that shortcut when every false value should be treated as “no items.” If callers might pass another meaningful false value, keep the explicit None branch.
Equality and identity: == [] versus is []
items == [] performs an equality comparison with an empty list and works when items is a list:
items = []
if items == []:
print("Equal to an empty list")
It is less general and less idiomatic than truth testing. A tuple, string, or another empty sequence will not compare equal to an empty list even though it is empty.
The Tool Desk
Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Never use items is [] as an emptiness test. The is operator tests object identity: whether both references point to the very same object. The literal [] creates a new list, so it normally has a different identity from items, even when both contain zero elements.
a = []
b = []
print(a == b) # True: equal contents
print(a is b) # False: different list objects
Reusable patterns for functions and defaults
Returning a Boolean
A function can return the truth value directly when its contract is “does this list contain anything?”:
def has_items(items):
return bool(items)
print(has_items([])) # False
print(has_items([1, 2, 3])) # True
In an if statement, the explicit bool() call is unnecessary. Returning items itself can also be useful when a caller wants the original list or a false value, but return bool(items) when the function promises a Boolean.
Safe default arguments
Do not use a mutable list as a default parameter. Create the list inside the function instead:
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
def add_tag(tag, tags=None):
if tags is None:
tags = []
tags.append(tag)
return tags
The None sentinel lets the function distinguish “caller omitted the argument” from a caller who intentionally supplied an existing, possibly empty list.
Removing items only when present
Check before removing a first element or before iterating over optional data:
pending = get_pending_jobs() # expected to return a list
while pending:
job = pending.pop()
process(job)
A while pending: loop naturally stops when the list becomes empty. If get_pending_jobs() may return None, normalize or branch before the loop rather than relying on an accidental false value.
Lists nested inside other data
Check the list at the level where it appears. A dictionary can exist while its list value is empty:
payload = {"errors": []}
if not payload["errors"]:
print("The request returned no errors")
When the key may be missing, use a default and decide whether a missing key should mean “empty”:
errors = payload.get("errors", [])
if errors:
print("Handle errors")
If a missing key is an error that must be reported, test membership first instead of silently supplying an empty list.
Custom sequence objects and truth testing
The same syntax works for objects that implement normal truth-value behavior. Python first uses __bool__(), or falls back to __len__(). A custom class can therefore define what “empty” means:
class Batch:
def __init__(self, records):
self.records = records
def __len__(self):
return len(self.records)
batch = Batch([])
if not batch:
print("The batch is empty")
For ordinary lists, this behavior is built in and predictable. If a third-party object has surprising truth semantics, consult its documentation or use its specific size API.
Free tools Windows power users keep installed
One-click scans. No signup required.
Common mistakes and their fixes
| Code or situation | What it does | Preferred fix |
|---|---|---|
if len(items): |
Works, but expresses a number as a Boolean and is discouraged by PEP 8 for sequence checks. | Use if items:. |
if not len(items): |
Works for sized objects, but is less clear than direct truth testing. | Use if not items:. |
if items is []: |
Tests identity against a newly created list, not contents. | Use if not items: or, rarely, items == []. |
if items == None: |
Uses equality for a singleton value and can behave unexpectedly with custom objects. | Use if items is None:. |
if items[0]: |
Raises IndexError for an empty list and tests the first element’s value, not list length. |
Guard with if items: first. |
Assuming None is a list |
Operations such as len(items) can raise TypeError. |
Handle None explicitly or normalize it. |
Choosing the right form
| Requirement | Expression | Reason |
|---|---|---|
| Run code only when the list is empty | if not items: |
Idiomatic direct truth test. |
| Run code only when at least one item exists | if items: |
Same rule, without negation. |
| Compare several count ranges | count = len(items) |
The numeric value is part of the decision. |
| Distinguish missing from empty | if items is None, then elif not items |
Separates two application states. |
| Compare list contents with another list | items == [] or another list value |
Equality is the actual requirement. |
Testing empty-list branches
Exercise both boundary states and a list containing false-looking values:
def label(items):
if not items:
return "empty"
return "non-empty"
assert label([]) == "empty"
assert label([0]) == "non-empty"
assert label([None, False]) == "non-empty"
assert label(["value"]) == "non-empty"
If your function accepts None, add a separate test for that state and decide whether it should return a special result or raise an error. Tests should also cover the type your API promises; accepting arbitrary objects can expose truth-value behavior you did not intend.
Performance, readability, and reliability notes
For built-in lists, if not items and len(items) == 0 both inspect list metadata rather than traversing every element. Choose based on intent, not on a presumed speed difference. Direct truth testing is shorter, follows PEP 8, and naturally generalizes to other sequences.
Keep the check close to the operation it protects. Validate a possibly absent value before calling len(), indexing, popping, or iterating. If an API guarantees a list, fail early on invalid types instead of silently converting unrelated false values into an empty list.
Quick wins for a faster PC:
Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Clear out junk files and repair common Windows errorsFree Scan →Scan for outdated or missing drivers - takes under a minuteDriver Scan →Best Value
Or skip the browser setup
If your development task also needs a webpage image for documentation, testing, or an AI workflow, ScreenshotNeo provides a separate website screenshot API; it is not a replacement for Python’s list check. One GET request returns a PNG, JPEG, WebP, or PDF. The service accepts cookie and consent banners before capture and removes more than 60 known consent platforms, newsletter popups, and chat widgets. Bot checks, CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and response headers identify the page verdict and billing status.
For a quick capture with cURL:
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
The same request in Python (see the ScreenshotNeo API documentation) is:
import requests
r = requests.get(
"https://api.screenshotneo.com/v1/shot",
params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"},
timeout=90,
)
r.raise_for_status()
open("shot.webp", "wb").write(r.content)
In 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}`);
if (!res.ok) throw new Error(`Screenshot failed: ${res.status}`);
const fs = await import('node:fs/promises');
await fs.writeFile('shot.webp', Buffer.from(await res.arrayBuffer()));
ScreenshotNeo also offers an MCP server with take_screenshot, get_page_info, and capture_pdf tools for Claude, Cursor, and other MCP clients. Its free plan includes 1,000 screenshots per month without a card; paid plans start at $5 for 3,000 shots, and every feature is available on every plan. Create a free ScreenshotNeo account.
Frequently Asked Questions
Does a list containing only False count as empty?
No. List truthiness depends on the number of elements, so [False] is non-empty even though its sole element is false.
Can I use the same check for a tuple or string?
Yes. Empty built-in sequences are false, so if not value: also handles an empty tuple or string. Keep the variable’s documented type clear.
What happens if the value is a generator?
Generators do not provide ordinary list-style emptiness without consuming values. Convert to a list only when buffering all values is acceptable, or iterate and track whether you received an item.
Should a function accept both None and lists?
Only if that distinction is part of its contract. Document the two states and test them separately; otherwise validate inputs and require one consistent type.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

