This article will cover how to handle exceptions in python list comprehensions.
I really enjoy using list comprehensions. It feels amazing to construct a nice list comprehension to make my code more readable and concise.
However, one thing that’s always annoyed be about list comprehensions is error handling.
The Problem With List Comprehensions and Exceptions
In particular, error handling can be a real pain when using functions inside list comprehensions.
Consider the following example:
You have a list of strings that each represent a percentage.
values = ['1.1%','2.0%','NA%','3.1%','5%','7.45%',]
Your task is to extract only the number from each string. We can do this with the following piece of code:
rates = [float(rate[:-1]) for value in values if rate]
But wait! As you can probably tell, NA is not a number, and because the float function has no way to handle this, it’s going to throw an exception.
So what are the options?
We could use a normal for loop with a try except block. And a lot of time time that can be a good choice. But for the purposes of this example, we want to see how we can handle errors using a list comprehension rather than a more traditional for loop.
OK, instead, we can filter out the unwanted values. And in this case, because we know that the list can contain a value of “NA%”, that will work. However, even though it works in this case, you won’t always know your values beforehand.
So, how can we tackle the case where you don’t know what values your input list will contain?
Fear not, there is a way to get both clean, concise looking code and robust error handling.
Catch function to the rescue!
def catch(func, *args, handle=lambda e : None, **kwargs):
return func(*args, **kwargs)
except Exception as e:
The credit for this nifty little code snippet goes to the user Bryan Head who shared this snippet in an answer to a question on stackoverflow. Thank’s Bryan.
This snippet is pretty sweet. This catch function accepts a function, args, kwargs, and optionally a custom exception handler.
You can now use this catch function as a wrapper to call whatever function you want.
You can also specify a custom handle function that will deal with any exception. By default, this handle function will just return None. In this case, that’s really useful since None can easily be filtered out in your list comprehension.
Here’s how we can apply the catch function to the previous example.
rates = [catch(float,rate[:-1]) for rate in rates if rate]
And that’s all there is to it. Now you can handle exceptions in list comprehensions.
I hope that was helpful.
If you like python and want to check check out more awesome python content, here are some other interesting python articles.