How to handle exceptions in the list of understandings?

I have some understanding of a list in Python in which every iteration can throw an exception.

For example , if I have:

eggs = (1,3,0,3,2) [1/egg for egg in eggs] 

I get a ZeroDivisionError exception in the third element.

How can I handle this exception and continue understanding the list?

The only way I can think of is to use a helper function:

 def spam(egg): try: return 1/egg except ZeroDivisionError: # handle division by zero error # leave empty for now pass 

But it looks a little bulky for me.

Is there a better way to do this in Python?

Note. . This is a simple example (see “for example” above) that I drew because my real example requires some context. I am not interested in avoiding division by zero errors, but in exception handling in list comprehension.

+86
python exception exception-handling list-comprehension
Oct. 06 '09 at 21:36
source share
6 answers

In Python, there is no built-in expression that allows you to ignore an exception (or return variable values ​​& c in case of exceptions), so in the literal sense it is impossible to “handle exceptions in the understanding of a list”, since List is an expression containing another expression, no more (t .e. not ), and only instructions can catch / ignore / handle exceptions).

Functional calls are an expression, and function bodies can include all the instructions you need, so delegating an exception-dependent subexpression evaluation of a function, as you have noticed, is one possible workaround (others, when possible, are value checks that can provoke exceptions also suggested in other answers).

The correct answers to the question "how to handle exceptions in the list comprehension" all express a part of all this truth: 1) literally, that is, lexically in the understanding itself, you cannot; 2) in practice, you delegate a task to a function or check error susceptibility values ​​when possible. Your reiteration that this is not an answer is thus unfounded.

+72
Oct 06 '09 at 22:10
source share

I understand that this question is quite old, but you can also create a generic function to make it easier:

 def catch(func, handle=lambda e : e, *args, **kwargs): try: return func(*args, **kwargs) except Exception as e: return handle(e) 

Then, as you understand it:

 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 descriptor function what you want (let's say you prefer to return "No" by default).

Hope this helps you or future viewers on this!

Note: in python 3, I would only make the argument keyword “handle” and put it at the end of the argument list. This would actually make passing arguments and thus catch much more natural.

+84
Jan 18 '12 at 18:48
source share

you can use

 [1/egg for egg in eggs if egg != 0] 

it will just skip the null elements.

+19
06 Oct '09 at 21:38
source share

There is no better way. In many cases, you can use avoidance like Peter.

Another option is not to use concepts

 eggs = (1,3,0,3,2) result=[] for egg in eggs: try: result.append(egg/0) except ZeroDivisionError: # handle division by zero error # leave empty for now pass 

It's up to you to decide whether it is more bulky or not.

+7
06 Oct '09 at 21:50
source share

I believe that the helper function proposed by those who ask the initial question and Brian Head is good and not cumbersome at all. The only line of magic code that does all the work is not always possible, so a helper function is the perfect solution if you want to avoid for loops. However, I would change it to the following:

 # A modified version of the helper function by the Question starter def spam(egg): try: return 1/egg, None except ZeroDivisionError as err: # handle division by zero error return None, err 

The output will be [(1/1, None), (1/3, None), (None, ZeroDivisionError), (1/3, None), (1/2, None)] . With this answer, you are in full control to continue, whatever you want.

+3
Nov 08 '16 at 10:23
source share

Often you can throw exceptions using if clauses that MAY be placed in a list comprehension:

 [1/egg if egg!=0 else 'whatever you want' for egg in eggs] 

This is not an exception, and you can handle the 0 case as you would like

0
Jan 22 '19 at 18:40
source share



All Articles