Archived

ternary conditionals

An old note — I haven't updated it since I wrote it.

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 and else 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')