/errors/python/zerodivisionerror-division-by-zero
ZeroDivisionError: division by zero
- tool
- Python
- exit code
- 1
- versions
- Python 3.x
- os
- any
ZeroDivisionError: division by zero means the right-hand side of / was 0. Python raises it for integers and floats. //, % and divmod() raise it too, with their own text. Check the divisor first, and ask why it is zero: it is often the length of an empty list.
Reproduce it
python -c "print(1 / 0)"Output · exit 1
Traceback (most recent call last):
File "<string>", line 1, in <module>
print(1 / 0)
~~^~~
ZeroDivisionError: division by zeroThe other operators use other messages
cat > ops.py <<'EOF'
for expr in ["1 / 0", "1 // 0", "1 % 0", "divmod(1, 0)", "1.0 / 0", "0 ** -1"]:
try:
eval(expr)
except ZeroDivisionError as e:
print(f"{expr:14} -> ZeroDivisionError: {e}")
EOF
python ops.pyOutput
1 / 0 -> ZeroDivisionError: division by zero 1 // 0 -> ZeroDivisionError: integer division or modulo by zero 1 % 0 -> ZeroDivisionError: integer modulo by zero divmod(1, 0) -> ZeroDivisionError: integer division or modulo by zero 1.0 / 0 -> ZeroDivisionError: float division by zero 0 ** -1 -> ZeroDivisionError: 0.0 cannot be raised to a negative power
Fix: guard the divisor
cat > avg.py <<'EOF'
def average(values):
return sum(values) / len(values) if values else 0.0
print(average([2, 4]))
print(average([]))
EOF
python avg.pyOutput
3.0 0.0
Other number types
Fraction and Decimal raise a ZeroDivisionError too, while some math functions report a zero divisor as a different exception:
cat > types.py <<'EOF2'
import math
from decimal import Decimal, DivisionByZero
from fractions import Fraction
print(issubclass(DivisionByZero, ZeroDivisionError))
for label, f in [("Fraction(1, 0)", lambda: Fraction(1, 0)),
("Decimal(1) / Decimal(0)", lambda: Decimal(1) / Decimal(0)),
("math.fmod(1, 0)", lambda: math.fmod(1, 0))]:
try:
f()
except ZeroDivisionError as e:
print(f"{label:24} -> {type(e).__name__}")
except ValueError as e:
print(f"{label:24} -> ValueError: {e}")
EOF2
python types.pyOutput
True Fraction(1, 0) -> ZeroDivisionError Decimal(1) / Decimal(0) -> DivisionByZero math.fmod(1, 0) -> ValueError: math domain error
How to recognise the cause
The traceback shows the line; the question is why the divisor is zero there. Print it, or the expression that produced it, just before the division:
| Divisor expression | Typical reason it is zero |
|---|---|
| len(items) | The list, query result or file was empty |
| count, total, n | A counter was never incremented because the loop did not run |
| end - start | Two timestamps or positions are equal, such as a very fast operation timed with a coarse clock |
| int(value) or float(value) | A missing field was read as 0, or a default of 0 was used |
| width, height, scale | An uninitialised size, such as a window or image that has not been laid out yet |
Choosing a fix
Guard the divisor when zero is a legitimate case with an obvious answer: an average of nothing can be 0.0 or None, a percentage of zero items can be shown as "n/a". Catch ZeroDivisionError when the division is deep inside a calculation and the caller decides what to show. If zero should never happen, do not hide it: raise a clear error earlier, for example ValueError("no samples"), so the real bug is found where it starts.
Prevention
Validate inputs where they enter the program, and make functions that divide by a length state what they return for an empty input. Tests with an empty list and with a single zero value catch most of these errors before production.
FAQ
Why does Python raise an error instead of returning infinity?
Python's int and float division raise ZeroDivisionError for a zero divisor rather than returning inf or nan. If you want IEEE-style results, use NumPy or check the divisor and return float('inf') yourself.
Can I catch a division by zero from the decimal module the same way?
Yes. With the default context, decimal raises decimal.DivisionByZero, which is a subclass of ZeroDivisionError, so except ZeroDivisionError catches it too.
Does math.fmod(x, 0) raise ZeroDivisionError?
No. math.fmod(1, 0) raises ValueError: math domain error, so code that uses math functions may need to catch ValueError as well.
Sources
- docs.python.orgdocs.python.org/3/library/exceptions.html#ZeroDivisionError
- docs.python.orgdocs.python.org/3/reference/expressions.html#binary-arithmetic-operations
- docs.python.orgdocs.python.org/3/library/stdtypes.html#numeric-types-int-float-complex
- docs.python.orgdocs.python.org/3/library/decimal.html#decimal.DivisionByZero