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 ?
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.