How to handle exceptions in a list comprehensions?
I realize this question is quite old, but you can also create a general function to make this kind of thing easier:
def catch(func, handle=lambda e : e, *args, **kwargs):
try:
return func(*args, **kwargs)
except Exception as e:
return handle(e)
Then, in your comprehension:
eggs = (1,3,0,3,2)
[catch(lambda : 1/egg) for egg in eggs]
[1, 0, ('integer division or modulo by zero'), 0, 0]
You can of course make the default handle function whatever you want (say you'd rather return 'None' by default).
Hope this helps you or any future viewers of this question!
Note: in python 3, I would make the 'handle' argument keyword only, and put it at the end of the argument list. This would make actually passing arguments and such through catch much more natural.
Update (9 years later...): For Python 3, I just meant switch *args
and handle
, so you can specify arguments to the function without specifying handle. A minor convenience:
def catch(func, *args, handle=lambda e : e, **kwargs):
try:
return func(*args, **kwargs)
except Exception as e:
return handle(e)
This is helpful when using a defined function in the comprehension:
from math import log
eggs = [1,3,0,3,2]
[catch(log, egg) for egg in eggs]
[0.0, 1.0986122886681098, ValueError('math domain error'), 1.0986122886681098, 0.6931471805599453]
Under the Python 2 version, we would've had to pass in handle
before the egg
.
There is no built-in expression in Python that lets you ignore an exception (or return alternate values &c in case of exceptions), so it's impossible, literally speaking, to "handle exceptions in a list comprehension" because a list comprehension is an expression containing other expression, nothing more (i.e., no statements, and only statements can catch/ignore/handle exceptions).
Function calls are expression, and the function bodies can include all the statements you want, so delegating the evaluation of the exception-prone sub-expression to a function, as you've noticed, is one feasible workaround (others, when feasible, are checks on values that might provoke exceptions, as also suggested in other answers).
The correct responses to the question "how to handle exceptions in a list comprehension" are all expressing part of all of this truth: 1) literally, i.e. lexically IN the comprehension itself, you can't; 2) practically, you delegate the job to a function or check for error prone values when that's feasible. Your repeated claim that this is not an answer is thus unfounded.
You can use
[1/egg for egg in eggs if egg != 0]
this will simply skip elements that are zero.