Make division by zero equal to zero

You can use a try/except block for this.

def foo(x,y):
    try:
        return x/y
    except ZeroDivisionError:
        return 0

>>> foo(5,0)
0

>>> foo(6,2)
3.0

I think try except (as in Cyber's answer) is usually the best way (and more pythonic: better to ask forgiveness than to ask permission!), but here's another:

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

One argument in favor of doing it this way, though, is if you expect ZeroDivisionErrors to happen often, checking for 0 denominator ahead of time will be a lot faster (this is 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)

Output:

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

So using try except turns out to be 3 to 4 times slower for lots of (or really, all) errors; that is: it is 3 to 4 times slower for iterations that an error is caught. The version using the if statement turns out to be slightly slower (10% or so) when there are few (or really, no) errors.


Check if the denominator is zero before dividing. This avoids the overhead of catching the exception, which may be more efficient if you expect to be dividing by zero a lot.

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

Solution

When you want to efficient handle ZeroDivisionError (division by zero) then you should not use exceptions or conditionals.

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

How it's works?

  • When b != 0 we have True and a / b or 0. True and a / b is equal to a / b. a / b or 0 is equal to a / b.
  • When b == 0 we have False and a / b or 0. False and a / b is equal to False. False or 0 is equal to 0.

Benchmark

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