如何在Python中处理列表解析中的异常?

我在Python中有一些列表理解,其中每次迭代都会抛出异常。

例如,如果我有:

eggs = (1,3,0,3,2)

[1/egg for egg in eggs]

我会在第3个元素中得到ZeroDivisionError异常。

如何处理此异常并继续执行列表推导?

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

def spam(egg):

try:

return 1/egg

except ZeroDivisionError:

# handle division by zero error

# leave empty for now

pass

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

有没有更好的方法在Python中执行此操作?

注意:这是我设计的一个简单示例(参见上面的“例如”),因为我的真实示例需要一些上下文。 我不想避免除零错误,而是处理列表理解中的异常。

5个解决方案

69 votes

我意识到这个问题已经很老了,但你也可以创建一个通用函数来简化这类事情:

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]

您当然可以根据需要设置默认句柄功能(假设您默认返回'无')。

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

注意:在python 3中,我只会创建'handle'参数关键字,并将其放在参数列表的末尾。 这将使实际传递参数,并通过捕获更加自然。

Bryan Head answered 2019-05-17T12:48:04Z

65 votes

Python中没有内置表达式可以让你忽略异常(或者在异常的情况下返回备用值和c),所以从字面上讲,“处理列表理解中的异常”是不可能的,因为列表理解是 包含其他表达式的表达式,仅此而已(即,没有语句,只有语句可以捕获/忽略/处理异常)。

函数调用是表达式,函数体可以包含你想要的所有语句,所以如你所知,将容易出错的子表达式的评估委托给一个函数是一种可行的解决方法(其他的,如果可行的话,是 检查可能引发异常的值,如其他答案中所建议的那样)。

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

Alex Martelli answered 2019-05-17T12:47:05Z

18 votes

您可以使用

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

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

Peter answered 2019-05-17T12:48:35Z

7 votes

不,没有更好的方法。 在很多情况下,你可以像彼得那样使用回避

你的另一个选择就是不要使用理解

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

由你来决定是否更麻烦

John La Rooy answered 2019-05-17T12:49:16Z

2 votes

我认为辅助功能,正如最初提出问题的人和Bryan Head所建议的那样,很好,而且根本不麻烦。 完成所有工作的单行魔术代码并不总是可行的,因此如果想要避免[(1/1, None), (1/3, None), (None, ZeroDivisionError), (1/3, None), (1/2, None)]循环,辅助函数是一个完美的解决方案。 但是我会修改它到这个:

# 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)].通过此答案,您可以完全控制以任何方式继续。

Elmex80s answered 2019-05-17T12:49:53Z