C40等于多少:使除以零等于零(python avoid division by zero)

如何忽略ZeroDivisionError并使n / 0 == 0

127

在除法之前检查分母是否为零。这避免了捕获异常的开销,如果您希望除以零很多,这可能会更有效。

def weird_division(n, d):
    return n / d if d else 0
41

您可以使用try/except块。

def foo(x,y):
    try:
        return x/y
    except ZeroDivisionError:
        return 0
>>> foo(5,0)
0
>>> foo(6,2)
3.0
25

解决方案

当你想有效地处理ZeroDivisionError(除以零),那么你不应该使用异常或条件。

result = b and a / b or 0  # a / b

它是如何工作的?

b != 0我们有True and a / b or 0.True and a / b等于a / b.a / b or 0等于a / b.

b == 0我们有False and a / b or 0.False and a / b等于False.False or 0等于0.

基准

Timer unit: 1e-06 s
Total time: 118.362 s
File: benchmark.py
Function: exception_div at line 3
Line #      Hits         Time  Per Hit   % Time  Line Contents
==============================================================
     3                                           @profile
     4                                           def exception_div(a, b):
     5 100000000   23419098.5      0.2     19.8      try:
     6 100000000   40715642.9      0.4     34.4          return a / b
     7 100000000   28910860.8      0.3     24.4      except ZeroDivisionError:
     8 100000000   25316209.7      0.3     21.4          return 0
Total time: 23.638 s
File: benchmark.py
Function: conditional_div at line 10
Line #      Hits         Time  Per Hit   % Time  Line Contents
==============================================================
    10                                           @profile
    11                                           def conditional_div(a, b):
    12 100000000   23638033.3      0.2    100.0      return a / b if b else 0
Total time: 23.2162 s
File: benchmark.py
Function: logic_div at line 14
Line #      Hits         Time  Per Hit   % Time  Line Contents
==============================================================
    14                                           @profile
    15                                           def logic_div(a, b):
    16 100000000   23216226.0      0.2    100.0      return b and a / b or 0
20

我认为tryexcept(如 Cyber 的答案)通常是最好的方法(更多的是 pythonic:请求宽恕比请求许可更好!),但这是另一个:

def safe_div(x,y):
    if y == 0:
        return 0
    return x / y

支持这样做的一个论点是,如果你期望ZeroDivisionErrors 经常发生,提前检查 0 分母会更快(这是 python 3):

import time
def timing(func):
    def wrap(f):
        time1 = time.time()
        ret = func(f)
        time2 = time.time()
        print('%s function took %0.3f ms' % (f.__name__, int((time2-time1)*1000.0)))
        return ret
    return wrap
def safe_div(x,y):
    if y==0: return 0
    return x/y
def try_div(x,y):
    try: return x/y
    except ZeroDivisionError: return 0
@timing
def test_many_errors(f):
    print("Results for lots of caught errors:")
    for i in range(1000000):
        f(i,0)
@timing
def test_few_errors(f):
    print("Results for no caught errors:")
    for i in range(1000000):
        f(i,1)
test_many_errors(safe_div)
test_many_errors(try_div)
test_few_errors(safe_div)
test_few_errors(try_div)

输出:

Results for lots of caught errors:
safe_div function took 185.000 ms
Results for lots of caught errors:
try_div function took 727.000 ms
Results for no caught errors:
safe_div function took 223.000 ms
Results for no caught errors:
try_div function took 205.000 ms

因此,使用tryexcept对于许多(或实际上是全部)错误会变慢 3 到 4 倍;也就是说:对于捕获错误的迭代,会变慢 3 到 4 倍。当错误很少(或实际上没有)时,使用if语句的版本会变慢一些(大约 10 %)。

本站系公益性非盈利分享网址,本文来自用户投稿,不代表边看边学立场,如若转载,请注明出处

(746)
如何创建数据库:无法使用“创建数据库”命令创建数据库
上一篇
好玩的3d游戏:导出Unity3D游戏
下一篇

相关推荐

发表评论

登录 后才能评论

评论列表(52条)