Python Basics: Checking Values with Truthiness, any, and all
Python conditions can use values directly. Empty containers and zero are false, which is convenient until zero or an empty value is meaningful. Make the intended test explicit.
These three standalone examples were tested on Linux with Python 3.12.14. They require no third-party packages. Assertions check the results; run without Python’s -O option.
Prepare a scratch directory
You need Bash, Python 3.12 or newer on your PATH, a text editor, and the mktemp, rm, and rmdir utilities. Keep using the same terminal and save each named source file as UTF-8.
start_dir="$PWD"
work_dir="$(mktemp -d)" || exit 1
cd -- "$work_dir" || exit 11. Preserve zero when applying a default
Save as default_attempts.py:
def attempts_or_default(value):
return 3 if value is None else value
assert attempts_or_default(0) == 0
assert attempts_or_default(None) == 3
print("Zero preserved:", attempts_or_default(0))
print("Missing default:", attempts_or_default(None))
print("Using or:", 0 or 3)
print("Nonempty string:", bool("False"))Run it:
python3 default_attempts.pyOutput:
Zero preserved: 0
Missing default: 3
Using or: 3
Nonempty string: Trueor returns one of its operands, not necessarily a boolean. It replaces every false value, including zero. Use an explicit None check when only missing values should get a default. The nonempty string “False” is true.
2. Require at least one valid item and validate all items
Save as validate_labels.py:
def valid_labels(labels):
return bool(labels) and all(label.strip() for label in labels)
assert valid_labels(["draft", "ready"]) is True
assert valid_labels(["draft", " "]) is False
assert valid_labels([]) is False
print(valid_labels(["draft", "ready"]))
print(valid_labels(["draft", " "]))
print(valid_labels([]))
print("Empty all:", all([]))
print("Empty any:", any([]))Run it:
python3 validate_labels.pyOutput:
True
False
False
Empty all: True
Empty any: FalseThis function expects a list of strings. all is true for an empty iterable, so bool(labels) enforces the separate requirement that the list contain something. The generator checks stripped text without building an intermediate list.
3. Observe short-circuit evaluation
Save as find_large_value.py:
def is_large(value):
print("Checking:", value)
return value >= 10
found = any(is_large(value) for value in [3, 12, 99])
assert found is True
print("Found:", found)Run it:
python3 find_large_value.pyOutput:
Checking: 3
Checking: 12
Found: Trueany stops at the first true result, so 99 is never checked. all similarly stops at the first false result. Use a generator expression for lazy tests; a list comprehension would run every test before any receives it.
When to use this
Use any for “at least one” and all for “every.” Both consume iterators only as far as needed, so a partly consumed iterator may still hold remaining values. For custom objects, truth testing can be defined with bool or len.
References
Clean up
In the same terminal, remove only these example files, then return to your original directory and remove the empty scratch directory:
rm -- default_attempts.py validate_labels.py find_large_value.py
cd -- "$start_dir" || exit 1
rmdir -- "$work_dir"
unset start_dir work_dirAcknowledgements
This post was created with assistance from AI.