TypeError: 'int' object is not iterable means Python tried to walk through the value one item at a time — in a for loop, an unpacking, a list() call, a sum() — and the value has no items. The type in the quotes is the diagnosis. Integers, floats, None, functions and most objects of your own classes are not iterable; lists, strings, dictionaries, sets, tuples, files and generators are.
What counts as iterable#
Anything Python can ask for “the next item” from. Concretely, an object with an __iter__ method, or the older __getitem__ protocol. Built in: list, tuple, str, dict, set, range, file objects, generators, and the results of map, zip, enumerate. Not iterable: numbers, None, booleans, functions, and plain class instances.
The operations that demand an iterable are more than just for: unpacking (a, b = x), star-args (f(*x)), list(x), set(x), sum(x), ", ".join(x), in on some types, and comprehensions.
‘int’ object is not iterable#
for i in len(items): # len returns an int
...
for i in range(len(items)): # range is iterable
...
for item in items: # usually what was meant anyway
...
The single most common form. Also seen as for i in 10: from other languages’ habits, and as sum(total) where total is already a number.
‘NoneType’ object is not iterable#
def get_names():
names = ["a", "b"]
# no return statement
for n in get_names(): # TypeError: 'NoneType' object is not iterable
...
names = ["b", "a"]
for n in names.sort(): # sort() sorts in place and returns None
...
for n in sorted(names): # sorted() returns a new list
...
A function without a return, or an in-place method (sort, append, extend, reverse, update) used as if it returned the collection. Also: a regular-expression search that matched nothing, a dict.get with no default, or a database call that found no rows. Check for None before iterating, or fix the function to return what it built.
‘function’ or ‘builtin_function_or_method’#
for key in config.keys: # forgot the brackets
...
for key in config.keys():
...
You iterated over the method itself rather than calling it. Add the brackets.
Cannot unpack non-iterable#
x, y = 5 # TypeError: cannot unpack non-iterable int object
x, y = get_point() # fine if get_point returns a tuple; fails if it returns None
for key, value in my_dict: # iterates keys only; each key is a string, unpacking a 3-char string into 2 fails
...
for key, value in my_dict.items():
...
The dictionary case deserves attention: iterating a dictionary gives keys, and unpacking a key that happens to be a two-character string works by accident and then fails on the first key of a different length. Use .items().
‘float’, ‘bool’ and other scalars#
Same story as int: a scalar where a collection was expected. Often a variable that held a list was reassigned to a total or a flag earlier in the function. Trace the name back to its last assignment.
Your own class#
class Deck:
def __init__(self):
self.cards = [...]
for card in Deck(): # TypeError: 'Deck' object is not iterable
...
Either iterate the attribute, for card in deck.cards, or make the class iterable:
class Deck:
def __init__(self):
self.cards = [...]
def __iter__(self):
return iter(self.cards)
for card in Deck(): # works; so do list(Deck()), len is separate
...
Returning iter(self.cards) delegates to the list’s iterator, which is the simplest correct implementation. A generator function using yield works too, and is the way to go when items are computed rather than stored.
Objects that look iterable and are not#
- A NumPy scalar or a pandas value that you expected to be an array: check
type(x). - A single JSON object where you expected a list: the API returned
{...}rather than[...]. - An integer read from a file that you meant to split into digits:
str(n)first.
Finding it#
print(type(thing), repr(thing)) # before the loop
Then look for where thing was assigned. The fix is almost always there — a missing return, a missing call, a reused name — not at the loop.
Questions people ask#
How is this different from “not subscriptable”?
Subscriptable is about square brackets; iterable is about loops and unpacking. A set is iterable but not subscriptable; an int is neither.
Is a string iterable?
Yes, character by character, which is sometimes the surprise: for x in "hello" gives letters, and ", ".join("hello") gives h, e, l, l, o.
Why does it say NoneType?
It is the type of None. The value you iterated was None.
Can a generator be iterated twice?
No; once exhausted it yields nothing, silently, with no error. If a second loop sees no items, that is why. Convert to a list if you need to iterate more than once.
Where to go next#
- “object is not subscriptable” — the square-bracket cousin.
- Generators and iterators — how iteration actually works.
- Python for loops — the basics.