以下示例非常简单。我想用一个可以引发异常的函数执行 map()。用一个例子来说会更清楚:
number_list = range(-2,8)
def one_divide_by(n):
return 1/n
try:
for number, divide in zip(number_list, map(one_divide_by, number_list)):
print("%d : %f" % (number, divide))
except ZeroDivisionError:
# Execution is stopped. I want to continue mapping
pass
当我执行此代码时,我得到:
-2 : -0.500000
-1 : -1.000000
这是由于我的列表中的0。我不想删除这个0(因为在实际情况下,我不能先知道我是否会得到Exception)。 你知道如何在异常后继续映射吗?
答案 0 :(得分:4)
你可以在你的函数中捕获异常(而不是在for
循环中)并在None
被引发时返回ZeroDivisionError
(或者你选择的任何东西):
def one_divide_by(n):
try:
return 1/n
except ZeroDivisionError:
return None
如果您选择return None
,则需要调整格式字符串;无法使用None
格式化%f
。
您可以返回的其他值(并且与您的字符串格式兼容)为float('inf')
(或float('-inf')
,具体取决于您的分子符号)或float('nan')
- &#34 ; INF inity这"或" n ot a n umber"。
here您会发现使用float('inf')
的一些注意事项。
答案 1 :(得分:3)
您可以在函数内移动try/except
块。示例 -
def one_divide_by(n):
try:
return 1/n
except ZeroDivisionError:
return 0 #or some other default value.
然后正常调用,不需要try / except块 -
for number, divide in zip(number_list, map(one_divide_by, number_list)):
print("%d : %f" % (number, divide))
答案 2 :(得分:2)
如果您可以替换 map
而不是更改函数 one_divide_by
的定义,我会推荐 more_itertools.map_except
:
from more_itertools import map_except
number_list = range(-2,8)
def one_divide_by(n):
return 1/n
for number, divide in map_except(
lambda number: (number, one_divide_by(number)),
number_list,
ZeroDivisionError
):
print(number, ':', divide)
这会打印,正如预期的那样:
-2 : -0.5
-1 : -1.0
1 : 1.0
2 : 0.5
3 : 0.3333333333333333
4 : 0.25
5 : 0.2
6 : 0.16666666666666666
7 : 0.14285714285714285
函数 more_itertools.map_except
接受一个函数、一个可迭代对象作为输入(就像内置的 map
)和预期的异常。当在映射过程中引发这些异常之一时,该元素将被简单地跳过。
此软件包可以使用 pip install more-itertools
安装,适用于 pip 用户,或使用 conda install -c conda-forge more-itertools
安装,适用于 Conda 用户。
答案 3 :(得分:0)
另一种选择是定义一个辅助函数,它接受这样的异常处理程序:
def map_e(function, *iterables, on_exception=None):
for elements in zip(*iterables):
try:
yield function(*elements)
except Exception as e:
yield on_exception(elements, exception=e) \
if callable(*on_exception) \
else None
list_a = [1, 2, 5, 1]
list_b = [2, -2, 6, 6]
list_c = [2, 1, 0, 8]
def sum_then_divide(a, b, c):
return (a + b) / c
def none_on_exception(*args, **kwargs):
return None
result = list(
map_e(
sum_then_divide,
list_a,
list_b,
list_c,
on_exception=none_on_exception
)
)
print(result)
不需要在你的主函数中处理异常,也不需要添加外部库。