TypeError: 'float' object cannot be interpreted as an integer
1 · The lesson
readWhat this error means
You gave a float — a number like 3.0 or 2.5 — to something that only works with whole numbers, and Python refused to round it for you. range() is the usual culprit, but random.randint(), str.zfill(), list.pop(), chr() and math.factorial() all raise the same error for the same reason.
Python won't convert even 3.0, which looks harmless. The rule is about the type, not the value: a float might be 3.0 today and 2.9999999999999996 after the next calculation, so Python makes you decide how to turn it into an int.
When you see it
Traceback (most recent call last): File "main.py", line 3, in <module> for i in range(half): ~~~~~^^^^^^ TypeError: 'float' object cannot be interpreted as an integer
When the float goes into a library function, the last frames are inside the library and the line you need is the one in your file:
Traceback (most recent call last): File "main.py", line 4, in <module> restock = random.randint(1, stock * 0.25) File "C:\Users\Ada\AppData\Local\Programs\Python\Python313\Lib\random.py", line 340, in randint return self.randrange(a, b+1) ~~~~~~~~~~~~~~^^^^^^^^ File "C:\Users\Ada\AppData\Local\Programs\Python\Python313\Lib\random.py", line 316, in randrange istop = _index(stop) TypeError: 'float' object cannot be interpreted as an integer
Why it happens
Almost always it is the / operator. In Python 3, / always returns a float, even when the division is exact:
orders = ["#1001", "#1002", "#1003", "#1004", "#1005", "#1006"] print(len(orders) / 2) # 3.0, a float, even though 6 divides evenly print(type(len(orders) / 2)) print(len(orders) // 2) # 3, an int
So this innocent-looking loop fails, because half is 3.0:
orders = ["#1001", "#1002", "#1003", "#1004", "#1005", "#1006"] half = len(orders) / 2 for i in range(half): print(orders[i])
The other sources of stray floats: multiplying by a percentage (stock * 0.25), anything from math.sqrt() or statistics.mean(), numbers read from JSON or a CSV and converted with float(), and round(x, 0), which — unlike round(x) — gives back a float.
The same mistake, different words
Use a float where Python wants an int in other places and the wording changes, which hides that it is the same bug:
| Code | Message |
|---|---|
range(6 / 2) | 'float' object cannot be interpreted as an integer |
"-" * (40 / 2) | can't multiply sequence by non-int of type 'float' |
[0] * (n / 2) | can't multiply sequence by non-int of type 'float' |
name[len(name) / 2] | string indices must be integers, not 'float' |
orders[len(orders) / 2] | list indices must be integers or slices, not float |
Every row has the same fix.
How to fix it
Use // when you mean "how many whole times". Floor division returns an int when both sides are ints, and it is what you almost always want for halves, pages and batches:
orders = ["#1001", "#1002", "#1003", "#1004", "#1005", "#1006", "#1007"] half = len(orders) // 2 for i in range(half): print(orders[i]) name = "Grace" print("Middle letter:", name[len(name) // 2]) print("-" * (40 // 2))
Use int(), round() or math.ceil() when the float comes from real arithmetic — and choose deliberately, because they disagree:
import math stock = 125 quarter = stock * 0.25 # 31.25 print(int(quarter)) # 31 - drops the fraction (towards zero) print(round(quarter)) # 31 - nearest whole number print(math.ceil(quarter)) # 32 - always rounds up print(round(quarter, 0)) # 31.0 - still a float, still breaks range() print(int(-7 / 2), -7 // 2) # -3 -4: int() and // differ for negatives
For "how many pages do 7 invoices need at 3 per page", math.ceil(7 / 3) (or -(-7 // 3)) is right and int(7 / 3) loses the last page. For a random restock amount, round() is fine:
import random random.seed(42) stock = 120 restock = random.randint(1, round(stock * 0.25)) print(f"Restocking {restock} of {stock}")
Check the value isn't secretly fractional. If int() silently dropping .5 would be a bug, test first: if not total.is_integer(): raise ValueError(...). Better to fail loudly than to process 2 orders out of 2.5.
When you'd actually see this in real code
- Splitting a dataset into training and test halves with
range(len(rows) / 2). - Pagination:
range(total_items / per_page)for page links. - Centring text in a terminal report:
" " * ((width - len(title)) / 2). - Porting old Python 2 code, where
/between two ints did floor division — the same line silently changed meaning in Python 3. - A config value like
"retries": 3.0from JSON, passed straight intorange().
Related errors
- TypeError: list indices must be integers or slices, not str — the same family: the wrong type used as an index.
- IndexError: string index out of range — once the index is an int, make sure it fits.
- ValueError: invalid literal for int() with base 10 — what
int("3.5")raises when the float is still a string. - ZeroDivisionError — the other thing that goes wrong with
/.
See Also
- All Python errors — the full index, by type and by when it happens.
- Numbers in depth
- Operators
- Loops (tutorial)
Found this useful? Share it with a friend who’s learning Python.