Python's if value: is concise, but it treats 0, an empty string, and None as false. If those values mean different things in your application, one condition should not collapse them into the same case.
bool(None) # False
bool(0) # False
bool("") # False
bool([]) # FalseA concise condition works well for an empty container
None, an empty list, and an empty string all take a falsy branch, but they need not represent the same state. If the number 0 is valid, check for a missing value separately with is None.
If you only need to know whether a list is empty, a simple condition works.
def normalize_items(items):
if not items:
return []
return items
assert normalize_items([]) == []
assert normalize_items(["api"]) == ["api"]This expresses the intent more naturally than len(items) == 0, and the pattern also works for strings and dictionaries.
But None enters the same branch. If “the list has not arrived” differs from “the list arrived empty,” check if items is None: first. Whether both states may appear as an empty list in the UI or one should be an error depends on the input contract.
If zero is valid, check for None explicitly
For a page number, inventory count, or discount rate where 0 is valid, if not value can become a bug.
def normalize_page(page):
if page is None:
return 0
return page
assert normalize_page(None) == 0
assert normalize_page(0) == 0
assert normalize_page(2) == 2Whether an empty string differs from one containing only spaces also depends on the service's rules. Before calling strip() everywhere, decide whether the original text must be preserved, and keep validation and normalization in one place.
During debugging, look beyond print(bool(value)): inspect type(value) and repr(value) too. The string "0" is truthy while the number 0 is falsy. Web inputs often arrive as strings, so conditions can change after conversion. Applying defaults at the input boundary avoids interpreting the same value differently at each call site.
Distinguish missing, null, and empty values in the input contract
Using only if not value for validation can reject a valid zero or empty collection. For an API request, decide separately whether an absent key, a present key with null, an empty string, and the number zero are allowed. Use is None when asking whether a value is missing; use if not value when intentionally grouping empty containers with other falsy values.
If you need to know the original state after supplying a default, do not keep only the normalized value. Page 0 and an unspecified page may both become 0, but logs and validation may still need to distinguish a normal request from an error.
Key takeaways
Python treats None, 0, empty strings, and empty containers as falsy. if not value suits a question about emptiness, but is None is necessary when zero and absence mean different things. Define which inputs are valid before writing the condition.

