Ternary expressions
Overview
A ternary expression (also called a conditional expression) evaluates to one of two values based on a condition, all in a single line. value_if_true if condition else value_if_false Examples: label = 'admin' if user['role'] == 'superuser' else 'member' display = name if name else 'Anonymous' status_text = 'enabled' if config.get('debug') else 'disabled' The expression evaluates the condition first, then returns exactly ONE of the two branches — the other is never evaluated. It is an expression, not a statement, so it can appear anywhere a value is expected. Common places include: - Variable assignments - Function arguments - `f-strings` - List elements Think of it as a compressed two-branch decision that returns a value — not a replacement for multi-branch logic. success = False # WRONG: Evaluates as ("Status: " + "OK") if success else "Error" msg = "Status: " + "OK" if success else "Error" # RIGHT: Parentheses force the ternary to evaluate first msg = "Status: " + ("OK" if success else "Error") Ternary expressions have very low precedence. Always wrap them in parentheses when combining them with other operations like string concatenation.
Ternary expressions compress routine two-outcome decisions into one readable line. Common examples include: - Present vs missing - Enabled vs disabled - Role A vs role B They become unreadable when nested or when the condition or branches are complex. Those cases still call for a full `if`/`else` block.
Where used: `FastAPI` response field serialization, `Pydantic` `computed_field` values, log message formatting
Why learn this
- Compressing simple two-branch assignments in `FastAPI` serializers and `Pydantic` models to a single readable line
- Reading library code and open-source projects that use conditional expressions extensively
Code walkthrough
user = {'name': 'alice', 'role': 'admin'}
label = 'Super User' if user['role'] == 'admin' else 'Regular User'
print(label)
Focus: The ternary evaluates the condition (`role == 'admin'`) and returns exactly one of the two string values — the other branch is never touched.
Common mistakes
- Nesting ternary expressions: `a if x else b if y else c` is legal but hard to read. Replace with a full `if`/`elif`/`else` block when there are more than two outcomes.
- Confusing the syntax order: Python's order is `value_if_true if condition else value_if_false` — the opposite of C's `condition ? true : false`. Write it as 'give me X, IF this is true, ELSE Y'.
- Using a ternary when the branches have side effects: Ternary expressions are for selecting values, not for branching on actions. If either branch calls a function for its side effect, a full `if`/`else` block is clearer.
- Forgetting parentheses in complex expressions: Ternary expressions have very low precedence. When combined with string concatenation or math, `"A" + "B" if True else "C"` evaluates as `("A" + "B") if True else "C"`. Always wrap the ternary in parentheses: `"A" + ("B" if True else "C")`.
Glossary
- side effect
- When a function or expression changes something outside of its own scope, like modifying a global variable or printing to the screen. Example: `print('done')`.
- conditional expression
- Another name for a ternary expression; a piece of code that evaluates a condition and returns one of two possible values. Example: `label = 'on' if enabled else 'off'`.
Recall questions
- What is the syntax of a Python ternary expression?
- When the condition is `False`, which branch is evaluated — the true branch or the false branch?
- When should you prefer a full `if`/`else` block over a ternary expression?
- Why should you wrap a ternary expression in parentheses when combining it with string concatenation?
Understanding checks
What does this code print?
Low
The condition `x > y` (`5 > 10`) is `False`, so the expression evaluates the branch after the `else`, skipping the `True` branch entirely.
Why shouldn't you nest ternary expressions like `a if x else b if y else c`?
Because it makes the code very difficult to read and understand. Use a full `if`/`elif`/`else` block whenever you have more than two possible outcomes.
Ternary expressions compress simple two-branch decisions into one line. For anything more complex or with multiple outcomes, a full `if`/`elif`/`else` block is much clearer.
Practice tasks
Role label formatter
Modify the format_role function to use a single ternary expression to return 'Admin (<name>)' when user['role'] == 'admin', and 'Guest (<name>)' for all other roles.
Challenge
Response status line builder
Write status_line(code, message=None) that returns a formatted string. Use a ternary so that when message is provided it reads '<code> <message>' and when it is None it reads '<code> (no message)'. Test with (200, 'OK'), (404, 'Not Found'), and (500, None).
Continue learning
Previous: if/elif/else and Python truthiness
Next: List Comprehensions