Python ZeroDivisionError: Division by Zero
1ZeroDivisionError: overview
A ZeroDivisionError means a division, floor division, modulo or power operation had zero as the divisor, which has no valid result.
Before this lesson: Python Operators, Python Exceptions: try, except, else and finally
2ZeroDivisionError: diagram
3ZeroDivisionError: explained step by step
A ZeroDivisionError means your code asked Python to divide by zero, or to take a remainder after dividing by zero. Mathematics has no answer for that, so Python stops instead of inventing one.
Which operations raise ZeroDivisionError
The message changes slightly with the operator, but the cause is always a zero on the right-hand side. All of Python's division-style operators are affected: /, //, % and divmod().
operations = {
"10 / 0": lambda: 10 / 0,
"10 // 0": lambda: 10 // 0,
"10 % 0": lambda: 10 % 0,
"10 / 0.0": lambda: 10 / 0.0,
"divmod(10, 0)": lambda: divmod(10, 0),
"0 ** -1": lambda: 0 ** -1,
}
for text, operation in operations.items():
try:
operation()
except ZeroDivisionError as err:
print(f"{text:14} -> {err}")Notice that 10 / 0.0 fails too. Unlike some languages, Python's floats do not quietly produce infinity when you divide by zero. Libraries such as NumPy do return inf (with a warning), but plain Python always raises.
How to read the traceback
Traceback (most recent call last):
File "stats.py", line 6, in <module>
print(average([]))
File "stats.py", line 3, in average
return sum(numbers) / len(numbers)
~~~~~~~~~~~~~^~~~~~~~~~~~~~
ZeroDivisionError: division by zero
- The last line shows the operator in use,
division by zero. - The innermost frame (the last
Fileentry) is where the division happens:sum(numbers) / len(numbers). - The frame above it shows the call that supplied the bad value:
average([]). The bug is usually here, in what you passed in, not in the division itself.
Cause 1: averaging an empty list
The most common real-world cause: dividing by len(...) of something that turned out to be empty, such as a filter with no matches.
def average(numbers):
return sum(numbers) / len(numbers)
print(average([4, 8, 6]))
try:
print(average([]))
except ZeroDivisionError as err:
print("ZeroDivisionError:", err)Cause 2: the user (or a data file) supplies zero
Anything that comes from outside your program can be zero: a form field, a CSV column, an API value. Convert it, then decide what zero should mean. See ValueError for the related problem of text that is not a number at all.
Cause 3: a computed denominator that ends up zero
ratio = passed / (total - failed) looks harmless until every test fails. When the divisor is itself a calculation, think about which inputs can make it zero.
Fix 1: guard with an if statement
Check the divisor first when zero is an expected situation, and choose what the result should be. The if/else lesson covers the syntax.
def safe_average(numbers):
if len(numbers) == 0:
return None # no data, so no average
return sum(numbers) / len(numbers)
print(safe_average([70, 90]))
print(safe_average([]))Return None, 0 or a message: which one is right depends on your program. An average of nothing is not zero, so None is often more honest.
Fix 2: catch the error with try/except
Use try and except when zero is rare, or when the check would be awkward to write. Catch ZeroDivisionError specifically, never a bare except, so that real bugs still show up.
def split_bill(total, people):
try:
return round(total / people, 2)
except ZeroDivisionError:
return "Add at least one person"
print(split_bill(90, 4))
print(split_bill(90, 0))Fix 3: validate input before the maths
When the zero comes from a user, reject it early with a clear message, ideally before any calculation. This keeps the division line simple and puts the explanation where the user can act on it.
Zero is not the same as "not a number"
The error only concerns an exact zero divisor. Using float("inf") or math.inf gives you a value that behaves like infinity without raising anything, and float("nan") represents "not a number". Neither is a replacement for checking your inputs, because they hide the problem rather than solve it. For statistics, the math and statistics lesson shows statistics.mean([]) raising a clearer StatisticsError for empty data.
If your message instead says unsupported operand type(s) for /, that is a TypeError: the types are wrong, not the value.
4ZeroDivisionError: syntax
a / b # true division -> "division by zero"
a // b # floor division -> "integer division or modulo by zero"
a % b # remainder -> "integer modulo by zero"
divmod(a, b)
if b != 0: # guard
result = a / b
try:
result = a / b
except ZeroDivisionError: # catch
result = None
5ZeroDivisionError: run the example
Press Run (or Ctrl + Enter). The output (step 6) appears directly below the code. Change anything and run it again.
def average(scores):
if not scores:
return None
return sum(scores) / len(scores)
classes = {"math": [80, 90, 70], "art": []}
for name, scores in classes.items():
result = average(scores)
if result is None:
print(name, "-> no scores yet")
else:
print(name, "->", result)
try:
print(sum([]) / len([]))
except ZeroDivisionError as err:
print("Unguarded:", err)Expected outputmath -> 80.0
art -> no scores yet
Unguarded: division by zero
7ZeroDivisionError: how the example works
Hover or tap a step to highlight its lines in the example above.
- Line 1-4
average()guards against the empty case.not scoresisTruefor an empty list, so the function returnsNonebefore any division can happen. - Line 6Two classes, one of which has no scores yet. This is the kind of data that causes the error in real programs.
- Line 8-9Loop over the dictionary, calling
average()for each list of scores. - Line 10-13A
Noneresult means "no data", so the program prints a friendly message. Otherwise it prints the average: (80 + 90 + 70) / 3 = 80.0. - Line 15-18The same average without the guard.
sum([])is 0 andlen([])is 0, so0 / 0raisesZeroDivisionError. Even0 / 0is an error in Python. Theexceptprints the message instead of crashing.
8ZeroDivisionError: common mistakes
Averaging an empty list
✗ Wrong
prices = []
average_price = sum(prices) / len(prices)✓ Right
prices = []
if prices:
average_price = sum(prices) / len(prices)
else:
average_price = None
print(average_price)An empty list has length 0. Check the list before dividing and decide what "no prices" should produce.
Modulo by zero when checking for even numbers
✗ Wrong
step = 0
for n in range(1, 5):
if n % step == 0:
print(n)✓ Right
step = 2
for n in range(1, 5):
if n % step == 0:
print(n)% also divides, so a zero on the right raises. Make sure the divisor is never zero, for example by rejecting it before the loop.
Floor division by zero when splitting items into groups
✗ Wrong
items = 10
groups = 0
per_group = items // groups✓ Right
items = 10
groups = 2
per_group = items // groups
print(per_group)// and divmod() raise the same error. Validate groups first and require at least one.
Expecting a float zero to give infinity
✗ Wrong
rate = 5 / 0.0✓ Right
divisor = 0.0
rate = 5 / divisor if divisor else None
print(rate)Plain Python does not return inf for float division. Guard the divisor whether it is an int or a float.
Catching the error too broadly
✗ Wrong
try:
share = total / people
except:
share = 0✓ Right
total, people = 90, 0
try:
share = total / people
except ZeroDivisionError:
share = 0
print(share)A bare except swallows every error, including typos, and quietly sets share to 0. Catch ZeroDivisionError only.
9ZeroDivisionError: exercises
Write your answer, then press Check. The checks run in your browser.
1. Predict which lines fail
Predict the output Easy ✓ CompletedRead the code and type exactly what it prints. Then press Check to compare.
for divisor in [4, 0, 2.5]:
try:
print(20 / divisor)
except ZeroDivisionError:
print("cannot divide by", divisor)
print("done")/ always returns a float. Only the zero raises, and the loop keeps going after the except block.5.0
cannot divide by 0
8.0
done
2. Fix the empty class average
Fix the bug Easy ✓ Completedaverage(scores) should return the mean of a list of scores, but it crashes for an empty list. Change it so an empty list returns 0 and other lists still return the mean.
def average(scores):
return sum(scores) / len(scores)
print(average([80, 90]))
print(average([]))len(scores) before dividing and return 0 straight away when it is empty.def average(scores):
if len(scores) == 0:
return 0
return sum(scores) / len(scores)
print(average([80, 90]))
print(average([]))
2 more exercises → 5 more examples
Questions learners ask
Why does Python raise ZeroDivisionError for 0/0 instead of returning NaN?
Plain Python checks the divisor only: any division by zero raises, even 0/0 or 5/0.0. NaN and inf can be created on purpose with float('nan') and float('inf'), and libraries like NumPy return them with a warning instead of raising, but the built-in operators never do.
Should I use try/except or an if check to avoid dividing by zero?
Use an if check when zero is a normal, expected case such as an empty list, because the code then says clearly what happens. Use try/except ZeroDivisionError when zero is rare or the divisor comes from a complex calculation that is hard to pre-check. Never use a bare except.
Is dividing by zero the same as 'integer division or modulo by zero'?
They are the same error class with different wording depending on the operator: '/' says 'division by zero', '//' and divmod() say 'integer division or modulo by zero', and '%' says 'integer modulo by zero'. In every case the right-hand number was zero.
Further reading
10Next lesson
Up nextPython FileNotFoundError: No such file or directoryA FileNotFoundError means Python tried to open or access a file or folder path that does not exist, usually because the…Related:
Python OperatorsPython Exceptions: try, except, else and finallyPython TypeError: What It Means and How to Fix ItPython ValueError
← Python ModuleNotFoundError: No module named · All Errors and Exceptions lessons · Practise in the IDE