ternary conditionals
Terneries in Python work just fine, however nested ternaries can lead to code that looks convoluted.
Standard form conditional
1i, j, r = 2, 3, 0
2if i > 1:
3 if j == 3:
4 r = 4
5 else:
6 r = 5
7else:
8 r = 6
9
10print(r)
Ternary
1i, j = 2, 3
2r = (4 if j == 3 else 5) if i > 1 else 5
3print(r)
As illustrated above, ternaries have some syntactic issues in python, imo:
- need disambiguating with parenthesis (this looks very confusing:
4 if j == 3 else 5 if i > 1 else 5
) - are backwards compared to c-based languages:
r = (i > 1 ? j == 3 ? 4 : 5 : 6)
- most of the space is taken up by the
if
andelse
statements, not the actual logic
Tuples
Our shortest version of the code above is:
1i, j = 2, 3
2r = (6, (5, 4)[j == 3])[i > 1]
3print(r)
We are converting the bool
result of the conditional to an int
(0
or 1
) which we then use for tuple indexing. Please note we're using tuples rather than lists, since their immutability makes them presumably more efficient.
There are several advantages:
- conditions are always in the square brackets
- values (or sub-conditionals) are always in the paren
- no extra paren required for readability
- extremely concise
When not to use
It's worth noting that, unlike with regular ternaries, each expression found as elements in a list or tuple declaration actually gets evaluated. This means you ought to use these only for simple ternary expressions. Using the results of functions is a no-no, since the function would actually get evaluated, whether the result is used or not.
Chained comparisons
On the subject of unconventional conditionals, it's worth explicitly noting that chaining comparisons is fine. Write a comparison so that when x is between 5 and 10 inclusive, the program prints 'in bounds' else it prints 'out of bounds'.
Solution
1for x in range(15):
2 print(f'{x}: in bounds' if 5 <= x <= 10 else f'{x}: out of bounds')