Skip to content
Happy Programming Guide
Start learning
Python

Fixing “TypeError: object is not iterable” in Python

You looped over, unpacked or converted something that has no items: an int, None, a function, or an object of your own class. The type in the message says which, and each has a fix.

Books and a notebook on a desk

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#

Python
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#

Python
def get_names():
    names = ["a", "b"]
    # no return statement

for n in get_names():         # TypeError: 'NoneType' object is not iterable
    ...
Python
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’#

Python
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#

Python
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#

Python
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:

Python
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#

Python
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#

Generators and iterators: what makes an object iterableRead next

Keep reading

Keep going — pick your next guide

The fastest way to improve is to read one guide, then build the thing it describes. Start with the basics, or jump straight to a project.

Ask a question or share what worked

Your email address will not be published. Required fields are marked *