Fix ZeroDivisionError in Python
Error Reference
ZeroDivisionError: division by zero
Division or modulo by zero is undefined. Guard against it.
Where zeros come from
Nobody writes x / 0 on purpose. The zero arrives in the data — most often from an empty collection feeding an aggregation:
grades = []
average = sum(grades) / len(grades)
Traceback (most recent call last):
File "report.py", line 2, in <module>
average = sum(grades) / len(grades)
~~~~~~~~~~~~^~~~~~~~~~~~~
ZeroDivisionError: division by zero
Other regulars: user input (int(input()) returning 0), and missing or zeroed fields in records — clicks / impressions for an ad nobody saw, a percentage over a total that happens to be 0. When this error fires, ask "which real-world situation makes this denominator zero?" — that situation usually deserves explicit handling, not just a patch.
Guards
Three patterns, depending on who should deal with the zero.
Raise early when a zero denominator means the caller made a mistake:
def average(total, count):
if count == 0:
raise ValueError("count cannot be zero")
return total / count
Return a sentinel when "no data" is a normal case, and let the caller decide what it means:
def average(values):
if not values:
return None # caller decides what an empty average means
return sum(values) / len(values)
print(average([80, 90])) # 85.0
print(average([])) # None
Catch the exception when the division is buried in an expression and a fallback is acceptable:
clicks, impressions = 12, 0
try:
rate = clicks / impressions
except ZeroDivisionError:
rate = 0.0
print(rate) # 0.0
Modulo and floor division raise it too
It's not just / — every division-family operator checks the denominator:
print(10 % 0) # ZeroDivisionError: integer division or modulo by zero
print(10 // 0) # same message
print(10 / 0.0) # ZeroDivisionError: float division by zero
So even/odd checks, hashing buckets (i % n), and pagination math (total // per_page) all crash when their right-hand side is zero.
Why 1 / 0 raises but overflow returns inf
Python floats can represent infinity — overflow quietly produces it:
print(1e308 * 10) # inf -- float overflow rounds to infinity
print(float('inf') / 5) # inf
print(1 / 0) # ZeroDivisionError: division by zero
The IEEE 754 float standard actually defines x / 0 as infinity, but Python deliberately raises instead: in ordinary code a zero denominator is almost always a logic error, and a loud exception at the division beats an inf silently propagating through later math.
Floats vs Decimal
decimal.Decimal lets you choose the IEEE-style behavior explicitly. By default it raises decimal.DivisionByZero (a subclass of ZeroDivisionError), but you can disable that trap and get infinity:
from decimal import Decimal, DivisionByZero, getcontext
print(Decimal(1) / Decimal(0)) # raises decimal.DivisionByZero
getcontext().traps[DivisionByZero] = False
print(Decimal(1) / Decimal(0)) # Infinity
Useful in financial or scientific pipelines where you want division-by-zero to flag a signal you inspect later rather than abort the computation.
Frequently Asked Questions
How do I just return 0 instead of crashing?
A conditional expression does it in one line. But be deliberate: silently returning 0 can hide bugs — an average of 0 ("students scored zero") is very different from no students at all. Prefer None or an exception when the caller needs to distinguish "empty" from "actually zero".
def safe_div(a, b, default=0.0):
return a / b if b else default
print(safe_div(10, 2)) # 5.0
print(safe_div(10, 0)) # 0.0
Does dividing by 0.0 behave differently than by 0?
No — plain Python raises ZeroDivisionError for both, just with the message "float division by zero". NumPy is the exception: dividing an array by zero emits a RuntimeWarning and returns inf (or nan for 0/0) instead of raising, following IEEE 754.
print(1 / 0.0)
# ZeroDivisionError: float division by zero
Can I catch every divide-by-zero variant at once?
except ZeroDivisionError already covers int, float, modulo, floor division, and decimal.DivisionByZero (a subclass). Its own parent is ArithmeticError, which additionally catches OverflowError — usually broader than you want, so stick with ZeroDivisionError.
try:
bucket = index % size
except ZeroDivisionError:
bucket = 0