Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ternary Operator with Exceptions?

I often find myself writing code such as:

try:
    name = names[2]
except IndexError:
    name = names[1]

or maybe:

try:
    name = Names.first
except AttributeError:
    name = Names.default

Since there is a nice syntax for ternary operators, I wondered if there was something similar for exceptions? Something like:

name = names[2] except IndexError names[1]

name = Names.first except AttributeError Names.default

which fits with the ternary operator style of:

name = names[2] if names[2] else names[1]
like image 563
QuantumChris Avatar asked Sep 12 '25 19:09

QuantumChris


2 Answers

There are no expressions for dealing with exceptions (though there is a rejected PEP that tried to introduce one). You can, however, avoid the exception in the first place.

name = names[2:0:-1][0]  # At the cost of making a small temporary list object

Assuming names has at least 2 values, the slice produces a list whose first element is either names[2] or names[1], depending on how many elements names actually has. Whichever one is the first element of the slice is retrieved using [0].

There's also no equivalent to dict.get that would let you write something like names.get(2, names[1]), though that suggests that perhaps your list should be a dict or something with more semantic structure.

like image 81
chepner Avatar answered Sep 14 '25 11:09

chepner


That syntax doesn't exist, but you can do something similar:

To handle IndexError, check if the index is within range:

name = names[2 if 2 in range(len(names)) else 1]

To handle AttributeError, use getattr with default value:

name = getattr(Names, 'first', Names.default)

Edit: As @chepner suggested, the first might be simplified to these as well:

name = names[2 if len(names) > 2 else 1]

name = names[min(len(names), 2)] # if len(names > 0) and you just want the last element.
like image 24
r.ook Avatar answered Sep 14 '25 10:09

r.ook