GICT knowledge base
Python if, elif and else: Conditions, Branches and Validation
Published
Use if, elif and else to choose a path through a Python program. Python checks the conditions in order and executes the first matching branch. An optional else handles the case where none matched; it does not catch exceptions.
These independent examples were tested with Python 3.12.14. Their thresholds are sample application rules, not hosting limits or service policies.
Start with a condition and an indented body
A condition can be any expression whose truth value Python can test. Use a colon after the condition and indent its body. A comparison such as pending > 0 produces a Boolean.
pending = 2
messages = []
if pending > 0:
messages.append("Work is waiting")
assert messages == ["Work is waiting"]
print(messages[0])
Use if, elif and else for mutually exclusive results
Branch order matters. Test the more restrictive high threshold before a lower threshold that would also match it. This function accepts a non-negative integer count and rejects inputs outside that contract. It explicitly rejects bool, which is a subclass of int.
def queue_state(pending):
if not isinstance(pending, int) or isinstance(pending, bool):
raise TypeError("pending must be an integer")
if pending < 0:
raise ValueError("pending cannot be negative")
if pending >= 10:
return "busy"
elif pending > 0:
return "waiting"
else:
return "empty"
assert queue_state(0) == "empty"
assert queue_state(1) == "waiting"
assert queue_state(9) == "waiting"
assert queue_state(10) == "busy"
assert queue_state(11) == "busy"
print(queue_state(10))
The checks before the branch selection are ordinary validation code. The assertions demonstrate expected results; do not replace input validation with assert, because Python can disable assertions in optimized mode.
Choose separate if statements when several actions may apply
An elif is not interchangeable with another if. In this example both notices are relevant, so evaluating only one would hide information.
disk_nearly_full = True
backup_overdue = True
notices = []
if disk_nearly_full:
notices.append("Check disk space")
if backup_overdue:
notices.append("Check backup schedule")
assert notices == ["Check disk space", "Check backup schedule"]
print(notices)
Combine conditions without confusing missing and zero
Use and when both requirements must hold, or for alternatives, and not to invert a truth value. A value of zero may be meaningful, so test is None when only a missing value should trigger a fallback.
def display_limit(value):
if value is None:
return "not configured"
if value == 0:
return "disabled"
return str(value)
def within_window(hour):
return 2 <= hour < 5
assert display_limit(None) == "not configured"
assert display_limit(0) == "disabled"
assert display_limit(12) == "12"
assert [within_window(h) for h in [1, 2, 4, 5]] == [False, True, True, False]
print(display_limit(0))
The window function expects a numeric hour; validating an actual timestamp, time zone and schedule is a separate task. See logical operators for short-circuit behavior and operand return values.
Nest a branch only when it depends on an earlier decision
Keep indentation readable. A guard clause, such as an early return, can make a deeply nested function easier to follow. For a short choice of one value, a conditional expression is another option.
def next_step(config_exists, config_valid):
if not config_exists:
return "create configuration"
if not config_valid:
return "repair configuration"
return "ready"
assert next_step(False, False) == "create configuration"
assert next_step(True, False) == "repair configuration"
assert next_step(True, True) == "ready"
enabled = False
label = "enabled" if enabled else "disabled"
assert label == "disabled"
print(label)
Handle conversion errors with try and except
Comparing an input string with a number is not the same as converting it. An else attached to if cannot recover from a failed int() call. Catch the specific conversion error when you have a useful response to it.
def parse_count(text):
try:
count = int(text)
except ValueError as error:
raise ValueError("Enter a whole-number count") from error
if count < 0:
raise ValueError("Count cannot be negative")
return count
assert parse_count("0") == 0
assert parse_count("12") == 12
for invalid in ["many", "-1"]:
try:
parse_count(invalid)
except ValueError:
pass
else:
raise AssertionError("Invalid input was accepted")
print(parse_count("12"))
When debugging, check == versus assignment =, colons, indentation, overlapping conditions and exact threshold values. Define every variable before using it. A username or email string being present does not authenticate a user; authentication requires a real identity-verification system, not a truthiness check.
Verification: All six blocks were executed independently. Additional checks cover invalid types and negative counts. Reference: Python’s control-flow tutorial.
Related guides
How to Deploy a FastAPI App with Gunicorn and Nginx
Deploy FastAPI behind Nginx with Gunicorn and systemd. Separate application packages, check HTTPS and verify worker replacement and application health.
PythonLearn How to Modify Python Dictionary Values Easily
Learn how to modify Python dictionary values effectively with various methods, including direct assignment, update(), and comprehensions, along with common mistakes to...
PythonPython Set Copy Tutorial: Avoid Common Mistakes and Data Errors
Learn how to copy sets in Python safely and efficiently while avoiding common mistakes. Explore methods like copy(), set(), and deepcopy().
PythonDifferent Methods to Loop Through Sets in Python (Beginner-Friendly Guide)
Learn diverse methods to loop through sets in Python, including practical examples and use cases, ideal for beginners looking to master set operations.
