How Can You Check If an Object Is Iterable?

You’ve probably already heard of iterable objects and iterators — and you’ve likely used them, too. These include any objects you can loop through using a for-loop, retrieving one element at a time.

(If you haven’t encountered them yet because you’re still at the beginning of your Python learning journey, it’s highly recommended to get familiar with these concepts as early as possible. Iterables and iterators are fundamental concepts and language features in Python, and you’ll come across them all the time.)

Now imagine this: you might want to write a function that accepts any iterable object — but fails or behaves incorrectly if the input isn’t iterable. So how can you reliably check if an object is truly iterable?

It’s commonly known that an object (let’s name it x) is iterable if it implements the __iter__ method. So when asked how to check if an object is iterable, the immediate answer might be to use the built-in hasattr(x, ‘__iter__’). This checks whether the object has an __iter__ method and returns True or False accordingly.

There’s another answer you might hear from those who are familiar with abstract base classes and the collections.abc module. They might suggest using isinstance(x, Iterable) to check whether x is an Iterable.

Of course, if these were the fully correct answers, there wouldn’t be much point in dedicating a whole blog post to the question. In reality, this is one of those “all bugs are insects, but not all insects are bugs” situations.

It’s true that any object that implements __iter__ is iterable. But the reverse is not necessarily true: not all iterable objects have an __iter__ method.

So which objects are iterable without defining __iter__?

The answer: those that implement __getitem__. This method accepts an index, slice, or key and returns the corresponding item.

At this point, someone more familiar with abstract base classes might say, “Alright, no problem — just check whether the object is of type Sequence or Mapping by calling isinstance(x, Sequence) or isinstance(x, Mapping).”
They might reason that both sequence and mapping types define __getitem__, so this should cover it.

While this is technically true, it’s not the right answer — because both Sequence and Mapping also define __iter__.

To illustrate all of this, below is a program that defines a custom class named Indexable where only __getitem__ is implemented, and __iter__ is not.
If you run this script, you’ll see that looping over an instance of this class still works just fine — even though __iter__ is not defined. When comparing it with the selected sequence, mapping, and set objects, the differences can be analyzed in the table following the program codes.

IterableSequenceMapping__iter____getitem__
list
range
dict
set
Indexable

Because of cases like this, the official Python documentation emphasizes that the only reliable way to determine whether an object is iterable is to try calling iter(x). If x is not iterable, this will raise a TypeError.

So, if you want to safely and reliably check whether an object is iterable, the recommended approach is to call the built-in iter(x) function within a tryexcept block.

This topic is also covered in more detail in the e-book Python Knowledge Building Step by Step, with practical examples that help deepen your understanding.

Interested in the e-book Python Knowledge Building Step by Step: From the Basics to Your First Desktop Application?