Search code examples
pythonexceptionlistcycle

Can I catch error in a list comprehensions to be sure to loop all the list items


I've got a list comprehensions which filter a list:

l = [obj for obj in objlist if not obj.mycond()]

but the object method mycond() can raise an Exception I must intercept. I need to collect all the errors at the end of the loop to show which object has created any problems and at the same time I want to be sure to loop all the list elements.

My solution was:

errors = []
copy = objlist[:]

for obj in copy:
    try:
        if (obj.mycond()):
            # avoiding to touch the list in the loop directly
            objlist.remove(obj) 
    except MyException as err:
        errors = [err]
if (errors):
   #do something

return objlist

In this post (How to delete list elements while cycling the list itself without duplicate it) I ask if there is a better method to cycle avoiding the list duplicate.

The community answer me to avoid in place list modification and use a list comprehensions that is applicable if I ignore the Exception problem.

Is there an alternative solution in your point of view ? Can I manage Exception in that manner using list comprehensions? In this kind of situation and using big lists (what I must consider big ?) I must find another alternative ?


Solution

  • I would use a little auxiliary function:

    def f(obj, errs):
      try: return not obj.mycond()
      except MyException as err: errs.append((obj, err))
    
    errs = []
    l = [obj for obj in objlist if f(obj, errs)]
    if errs:
      emiterrorinfo(errs)
    

    Note that this way you have in errs all the errant objects and the specific exception corresponding to each of them, so the diagnosis can be precise and complete; as well as the l you require, and your objlist still intact for possible further use. No list copy was needed, nor any changes to obj's class, and the code's overall structure is very simple.