我如何处理Python中的列表理解exception?

我有一些Python中的列表理解,其中每个迭代可以抛出一个exception。

例如 ,如果我有:

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

我会在第三个元素中得到一个ZeroDivisionErrorexception。

我如何处理这个exception并继续执行列表理解?

我能想到的唯一方法是使用一个辅助函数:

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

但是这对我来说看起来有点麻烦。

有没有更好的方法来在Python中做到这一点?

注意:这是一个简单的例子(参见上面的“ 例如 ”),因为我的真实例子需要一些上下文。 我不想避免被零错误分割,而是在列表理解中处理exception。

在Python中没有内build的expression式可以让你忽略exception(或者在exception情况下返回替代值&c),所以从字面上来说,“处理列表理解中的exception”是不可能的,因为列表理解是一个expression式包含其他expression式,仅此而已(即没有语句,只有语句可以捕获/忽略/处理exception)。

函数调用是expression式,并且函数体可以包含所有你想要的语句,所以如你所注意的那样,把一个容易出现exception的子expression式的评估委托给一个函数是一个可行的解决方法(其他的,如果可行的话)是检查可能引发exception的值,正如其他答案中所build议的那样)。

对“如何处理列表理解中的例外”这个问题的正确回答都是这个真理的一部分:1)从字面上来看,即词汇在理解本身中,你不能; 2)实际上,您将作业委托给一个函数,或者在可行的情况下检查容易出错的值。 你一再声称,这不是一个答案是没有根据的。

我意识到这个问题是相当古老的,但你也可以创build一个通用的function,使这种事情更容易:

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

那么,在你的理解中:

 eggs = (1,3,0,3,2) [catch(lambda : 1/egg) for egg in eggs] [1, 0, ('integer division or modulo by zero'), 0, 0] 

当然,你可以使用默认的句柄函数(比如默认情况下返回'None')。

希望这可以帮助你或任何未来的观众这个问题!

注意:在Python 3中,我只会将“handle”参数关键字放在参数列表的末尾。 这实际上会使争论变得更加自然。

您可以使用

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

这将简单地跳过零的元素。

不,没有更好的办法。 在很多情况下,你可以像Peter一样避免使用

你的其他select是不使用理解

 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 

由你决定是否更麻烦

我认为帮助者的function,正如那个问最初的问题和Bryan Head的人所build议的那样,是好的,而且不麻烦。 完成所有工作的一行魔术代码并不总是可能的,所以如果想要避免循环,辅助函数是一个完美的解决scheme。 但是我会修改它到这个:

 # 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 

输出将是[(1/1, None), (1/3, None), (None, ZeroDivisionError), (1/3, None), (1/2, None)] 。 有了这个答案,你完全可以继续以任何你想要的方式。