Python TypeError: 'int' Object Is Not Iterable — How to Fix It
TypeError: 'int' object is not iterable
This error means you’re trying to loop over, unpack, or pass a number to a function that expects something iterable (like a list, tuple, string, or range). Python can’t iterate over a single integer because there’s nothing to step through.
Why this happens
In Python, iteration means going through items one by one. Lists, strings, tuples, dictionaries, sets, and generators are all iterable — they contain multiple elements. An integer is a single value with no elements to iterate over.
This error appears in several contexts:
forloops- Unpacking assignments (
a, b = ...) - Built-in functions that expect iterables (
sum(),list(),tuple(),join(),min(),max()) - List comprehensions
- The
*unpacking operator
Fix 1: Use range() in for loops
The most common beginner mistake — trying to loop “5 times” by writing for i in 5.
# ❌ Can't iterate over a number
for i in 5:
print(i)
# ✅ Use range() to generate a sequence
for i in range(5):
print(i) # 0, 1, 2, 3, 4
# ✅ Start from 1
for i in range(1, 6):
print(i) # 1, 2, 3, 4, 5
# ✅ With step
for i in range(0, 10, 2):
print(i) # 0, 2, 4, 6, 8
range(n) creates an iterable sequence from 0 to n-1. It doesn’t create a list in memory — it generates values on demand, making it efficient even for large numbers.
Fix 2: Passing an int to functions that expect iterables
Many built-in functions require an iterable argument. Passing a single number directly will fail.
# ❌ sum() expects an iterable
total = sum(5) # TypeError!
# ✅ Pass a list or tuple
total = sum([1, 2, 3, 4, 5])
total = sum((1, 2, 3, 4, 5))
# ❌ min/max with a single int
smallest = min(5) # TypeError!
# ✅ Pass multiple arguments or an iterable
smallest = min(5, 10, 3)
smallest = min([5, 10, 3])
# ❌ join() expects an iterable of strings
result = ", ".join(42) # TypeError!
# ✅ Convert to string first, then wrap in a list
result = ", ".join([str(42)]) # "42"
# ✅ Or join a list of strings
result = ", ".join(["1", "2", "3"]) # "1, 2, 3"
# ❌ list() expects an iterable
my_list = list(5) # TypeError!
# ✅ Wrap in a list literal
my_list = [5]
# ✅ Or use range
my_list = list(range(5)) # [0, 1, 2, 3, 4]
Fix 3: A function returns an int instead of a list
This is a subtle bug. You call a function expecting it to return a list, but it returns a count or status code instead.
def get_items(category):
items = db.query(category)
return len(items) # ❌ Returns the count, not the items!
# Trying to iterate over the return value
for item in get_items("books"): # TypeError: 'int' is not iterable
print(item)
# ✅ Fix: return the actual list
def get_items(category):
items = db.query(category)
return items # Return the list itself
Another common variant — accidentally returning from the wrong branch:
def fetch_users(active_only=True):
users = load_all_users()
if active_only:
return len([u for u in users if u.active]) # ❌ Returns int!
return users
# ✅ Fix
def fetch_users(active_only=True):
users = load_all_users()
if active_only:
return [u for u in users if u.active] # Return filtered list
return users
Fix 4: Unpacking a single integer
Python’s unpacking syntax requires an iterable on the right side.
# ❌ Can't unpack a single int into multiple variables
a, b = 5 # TypeError!
# ✅ Unpack a tuple or list
a, b = 5, 10
a, b = [5, 10]
a, b = (5, 10)
This also happens with function returns:
def get_coordinates():
return 0 # ❌ Returns a single int
x, y = get_coordinates() # TypeError!
# ✅ Return a tuple
def get_coordinates():
return (0, 0)
x, y = get_coordinates() # Works
Fix 5: Using * unpacking on an int
# ❌ Can't unpack an int
numbers = 5
print(*numbers) # TypeError!
# ✅ Unpack an iterable
numbers = [1, 2, 3, 4, 5]
print(*numbers) # 1 2 3 4 5
Fix 6: List comprehension over an int
count = 10
# ❌ Can't iterate over count
squares = [i**2 for i in count] # TypeError!
# ✅ Use range()
squares = [i**2 for i in range(count)] # [0, 1, 4, 9, ...]
Fix 7: Variable shadowing
A common trap — you accidentally reassign a list variable to its length or an index.
items = [1, 2, 3, 4, 5]
items = len(items) # Now items is 5, not a list!
for item in items: # TypeError: 'int' is not iterable
print(item)
Fix: Use different variable names, or don’t reassign.
items = [1, 2, 3, 4, 5]
count = len(items) # Separate variable for the count
for item in items: # Works fine
print(item)
How to debug
When you hit this error, check the type of what you’re iterating over:
data = get_something()
print(f"Type: {type(data)}, Value: {data}")
# Output: Type: <class 'int'>, Value: 42
Then trace back to where data was assigned. Common culprits:
- A function that returns
len()instead of the collection - A variable that was reassigned from a list to an int
- An API response field that’s a number instead of an array
Prevention with type hints
Type hints won’t prevent the error at runtime, but they help catch it during development with tools like mypy:
from typing import List
def get_items() -> List[str]: # Declares return type
items = fetch_from_db()
return len(items) # mypy will flag this as an error
FAQ
What about ‘float’ object is not iterable?
Same cause, same fixes. You’re passing a float (like 3.14) where an iterable is expected. Use range() for loops, or wrap the value in a list.
Can I make a custom class iterable?
Yes. Implement the __iter__ method:
class Countdown:
def __init__(self, start):
self.start = start
def __iter__(self):
for i in range(self.start, 0, -1):
yield i
for n in Countdown(5):
print(n) # 5, 4, 3, 2, 1
Why does for i in "hello" work but for i in 5 doesn’t?
Strings are iterable — Python can step through each character. Integers have no internal sequence to step through. There’s no meaningful way to “iterate over 5.”
How is this different from “object is not subscriptable”?
“Not iterable” means you can’t loop over it. “Not subscriptable” means you can’t index it with [0]. Both happen when you treat a non-collection type as a collection. See TypeError: object is not subscriptable — Fix.