如何处理列表推导式中的异常?
我在 Python 中有一些列表理解,其中每次迭代都可能抛出异常。
例如,如果我有:
eggs = (1,3,0,3,2)
[1/egg for egg in eggs]
我会在第三个元素中收到 ZeroDivisionError
异常。
如何处理此异常并继续执行列表理解?
我能想到的唯一方法是使用辅助函数:
def spam(egg):
try:
return 1/egg
except ZeroDivisionError:
# handle division by zero error
# leave empty for now
pass
但这对我来说看起来有点麻烦。
在 Python 中是否有更好的方法来做到这一点?
注意:这是我设计的一个简单示例(参见上面的“例如”),因为我的真实示例需要一些上下文。我对避免除以零错误不感兴趣,但对处理列表理解中的异常感兴趣。
I have some a list comprehension in Python in which each iteration can throw an exception.
For instance, if I have:
eggs = (1,3,0,3,2)
[1/egg for egg in eggs]
I'll get a ZeroDivisionError
exception in the 3rd element.
How can I handle this exception and continue execution of the list comprehension?
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 this looks a bit cumbersome to me.
Is there a better way to do this in Python?
Note: This is a simple example (see "for instance" above) that I contrived because my real example requires some context. I'm not interested in avoiding divide by zero errors but in handling exceptions in a list comprehension.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
我意识到这个问题已经很老了,但是您也可以创建一个通用函数来使这种事情变得更容易:
然后,在您的理解中:
您当然可以使默认句柄函数成为您想要的任何内容(假设您宁愿返回'默认情况下无)。
注意:在 python 3 中,我将仅使用“handle”参数关键字,并将其放在参数列表的末尾。这将使实际传递参数等通过 catch 变得更加自然。
更新(9年后...):对于Python 3,我只是指切换
*args
和handle
,这样你就可以指定函数的参数而不指定句柄。一个小便利:这在推导式中使用定义的函数时很有帮助:
在 Python 2 版本下,我们必须在
egg
之前传入handle
。I realize this question is quite old, but you can also create a general function to make this kind of thing easier:
Then, in your comprehension:
You can of course make the default handle function whatever you want (say you'd rather return 'None' by default).
Note: in python 3, I would make the 'handle' argument keyword only, and put it at the end of the argument list. This would make actually passing arguments and such through catch much more natural.
Update (9 years later...): For Python 3, I just meant switch
*args
andhandle
, so you can specify arguments to the function without specifying handle. A minor convenience:This is helpful when using a defined function in the comprehension:
Under the Python 2 version, we would've had to pass in
handle
before theegg
.Python 中没有内置表达式可以让您忽略异常(或在异常情况下返回备用值 &c),因此从字面上讲,“在列表推导式中处理异常”是不可能的,因为列表推导式是一个包含其他表达式的表达式,仅此而已(即,没有语句,并且只有语句可以捕获/忽略/处理异常)。
函数调用是表达式,函数体可以包含您想要的所有语句,因此将容易出现异常的子表达式的计算委托给函数,正如您所注意到的,是一种可行的解决方法(其他可行的方法是检查可能引发异常的值,正如其他答案中所建议的那样)。
对“如何处理列表推导式中的异常”问题的正确回答都表达了这个事实的一部分:1)从字面上看,即在推导式本身的词汇上,你不能; 2)实际上,您可以将工作委托给一个函数,或者在可行的情况下检查容易出错的值。因此,您反复声称这不是答案是没有根据的。
There is no built-in expression in Python that lets you ignore an exception (or return alternate values &c in case of exceptions), so it's impossible, literally speaking, to "handle exceptions in a list comprehension" because a list comprehension is an expression containing other expression, nothing more (i.e., no statements, and only statements can catch/ignore/handle exceptions).
Function calls are expression, and the function bodies can include all the statements you want, so delegating the evaluation of the exception-prone sub-expression to a function, as you've noticed, is one feasible workaround (others, when feasible, are checks on values that might provoke exceptions, as also suggested in other answers).
The correct responses to the question "how to handle exceptions in a list comprehension" are all expressing part of all of this truth: 1) literally, i.e. lexically IN the comprehension itself, you can't; 2) practically, you delegate the job to a function or check for error prone values when that's feasible. Your repeated claim that this is not an answer is thus unfounded.
您可以使用
它来简单地跳过零元素。
You can use
this will simply skip elements that are zero.
不,没有更好的办法了。在很多情况下,你可以像彼得一样使用回避
你的另一个选择是不使用推导式
由你来决定这是否更麻烦
No there's not a better way. In a lot of cases you can use avoidance like Peter does
Your other option is to not use comprehensions
Up to you to decide whether that is more cumbersome or not
我认为,正如提出最初问题的人和 Bryan Head 所建议的那样,辅助函数很好,而且一点也不麻烦。一行神奇代码完成所有工作并不总是可能的,因此如果想避免
for
循环,辅助函数是一个完美的解决方案。不过我会将其修改为这个:输出将是这个
[(1/1, None), (1/3, None), (None, ZeroDivisionError), (1/3, None), (1 /2,无)]
。有了这个答案,您就可以完全控制以任何您想要的方式继续。替代:
是的,返回错误,而不是引发错误。
I think a helper function, as suggested by the one who asks the initial question and Bryan Head as well, is good and not cumbersome at all. A single line of magic code which does all the work is just not always possible so a helper function is a perfect solution if one wants to avoid
for
loops. However I would modify it to this one:The output will be this
[(1/1, None), (1/3, None), (None, ZeroDivisionError), (1/3, None), (1/2, None)]
. With this answer you are in full control to continue in any way you want.Alternative:
Yes, the error is returned, not raised.
我没有看到任何答案提到这一点。
但此示例是防止已知失败案例引发异常的一种方法。
I didn't see any answer mention this.
But this example would be one way of preventing an exception from being raised for known failing cases.
您可以使用生成器:
You can use generators: