Conditionals
Conditionals let your code make decisions. They’re at the heart of control flow in Python. Clear conditionals with well-thought-out checks make your code easier to follow and less prone to logical errors. Poorly written ones produce erroneous logic that’s hard to debug.
When you write conditionals, these best practices can make your logic clearer and less error-prone:
- Use guard clauses to reduce nesting. Prefer returning early for invalid cases (
if not data: return ...) instead of wrapping most of your function in a bigifblock. This pattern flattens your code, making the happy path easier to read. - Prefer truthy checks where appropriate. Use patterns like
if items:instead ofif len(items) > 0:andif not text:instead ofif text == "":when you only care whether a value is empty. This leverages Python’s built-in truth value testing, keeping conditionals concise. But, avoid truthy checks when0,False, or other falsy values are meaningful. - Avoid deeply nested conditionals. Favor flat conditionals over several levels of nesting. Multiple layers of nesting make code harder to reason about and easier to break during refactoring.
- Favor explicit conditions. For
Nonechecks and numeric ranges, write conditions likeif value is None:instead ofif not value:andif 0 <= rate <= 1:instead ofif rate >= 0 and rate <= 1:. Explicit comparisons better communicate intent and reduce ambiguity. - Use Boolean operators and parentheses for clarity. Combine related checks with
andandor, and use parentheses to group the logical components of compound conditions. This practice makes your intent clearer and helps you avoid operator-precedence mistakes, especially in longer conditions. - Use the walrus operator (
:=) when appropriate to reduce duplication. Use assignment expression to make a condition more concise by computing a value once and reusing it. If a walrus expression makes the condition harder to read or hides important side effects, prefer a separate assignment statement instead. - Favor
dictdispatch or pattern matching over longif/elifchains. When branching on a single value, a dispatch dictionary or amatchstatement is often clearer and easier to extend than a long chain ofelifclauses.
To see these ideas in action, consider the following function that computes a shipping cost:
🔴 Avoid this:
def shipping_cost(country, items):
if country is not None:
if country == "US":
if len(items) > 0: # Non-empty cart?
if len(items) > 10: # Free shipping?
return 0
else:
return 5
else:
return 0
elif country == "CA":
if len(items) > 0: # Non-empty cart?
return 10
else:
return 0
else:
# Other countries
if len(items) > 0: # Non-empty cart?
return 20
else:
return 0
else:
raise ValueError("invalid country")
This function works, but it’s deeply nested, repeats len(items) checks, and hides the invalid country case at the bottom. It’s hard to follow the logic at a glance.
✅ Favor this:
def shipping_cost(country, items):
if country is None:
raise ValueError("invalid country")
if not items: # Empty cart?
return 0
if country == "US":
return 0 if len(items) > 10 else 5
if country == "CA":
return 10
return 20 # Other countries
In this version, guard clauses handle invalid inputs and empty carts up front, eliminating unnecessary nesting. Note how you rely on Python’s truthy checks for items instead of using len() explicitly. The logic for each country is easier to read, and repeated checks are removed.
Although this version uses multiple if statements instead of elif, each branch returns early, making the control flow explicit and safe.
For more complex routing based on a single value, you could also replace the if chain with a dispatch dictionary or a match statement, which is often even clearer.
Related Resources
Tutorial
Conditional Statements in Python
In this step-by-step tutorial you'll learn how to work with conditional ("if") statements in Python. Master if-statements and see how to write complex decision making code in your programs.
For additional information on related topics, take a look at the following resources:
- Control Flow Structures in Python (Tutorial)
- Python Booleans: Use Truth Values in Your Code (Tutorial)
- Using the "and" Boolean Operator in Python (Tutorial)
- Using the "or" Boolean Operator in Python (Tutorial)
- Using the "not" Boolean Operator in Python (Tutorial)
- Python's "in" and "not in" Operators: Check for Membership (Tutorial)
- Why Are Membership Tests So Fast for range() in Python? (Tutorial)
- Python != Is Not is not: Comparing Objects in Python (Tutorial)
- The Walrus Operator: Python's Assignment Expressions (Tutorial)
- LBYL vs EAFP: Preventing or Handling Errors in Python (Tutorial)
- Conditional Statements in Python (if/elif/else) (Course)
- Python Conditional Statements (Quiz)
- Control Flow Structures in Python (Quiz)
- Python Booleans: Leveraging the Values of Truth (Course)
- Using the Python and Operator (Course)
- Using the Python or Operator (Course)
- Using the "or" Boolean Operator in Python (Quiz)
- Using the Python not Operator (Course)
- Checking for Membership Using Python's "in" and "not in" Operators (Course)
- Comparing Python Objects the Right Way: "is" vs "==" (Course)
- Python Assignment Expressions and Using the Walrus Operator (Course)
- The Walrus Operator: Python's Assignment Expressions (Quiz)
- Handling or Preventing Errors in Python: LBYL vs EAFP (Course)