How to determine if an object is iterable in Python?

To determine if an object is iterable in Python (i.e., can be used in loops like for or with iter()), you can use the following methods:

1. Check Using collections.abc.Iterable

The standard way to check if an object is iterable (supports __iter__ method).
Note: This works for most built-in iterables but may miss objects that use __getitem__ for iteration.

from collections.abc import Iterable

def is_iterable(obj):
    return isinstance(obj, Iterable)

# Examples:
print(is_iterable([1, 2, 3]))    # True (list is iterable)
print(is_iterable("hello"))      # True (string is iterable)
print(is_iterable(123))          # False (int is not iterable)

2. Attempt to Call iter() (EAFP Principle)

A more reliable method that works for objects using __iter__ or __getitem__ for iteration.
Pythonic approach: “Easier to Ask for Forgiveness than Permission” (EAFP).

def is_iterable(obj):
    try:
        iter(obj)
        return True
    except TypeError:
        return False

# Examples:
print(is_iterable({"a": 1}))     # True (dict is iterable)
print(is_iterable(3.14))         # False (float is not iterable)

# Works for custom classes with __getitem__
class MySequence:
    def __getitem__(self, index):
        return index

my_seq = MySequence()
print(is_iterable(my_seq))       # True (uses __getitem__)

3. Check for __iter__ or __getitem__ (Advanced)

Explicitly check for iteration methods (covers most cases, but not foolproof).

def is_iterable(obj):
    return hasattr(obj, '__iter__') or hasattr(obj, '__getitem__')

# Example:
class CustomIterable:
    def __iter__(self):
        yield 1

class CustomSequence:
    def __getitem__(self, index):
        return index

print(is_iterable(CustomIterable()))  # True (has __iter__)
print(is_iterable(CustomSequence()))  # True (has __getitem__)
print(is_iterable(True))              # False (bool has neither)

Key Differences

MethodCovers __iter__Covers __getitem__Notes
collections.abc.IterableYesNoMisses old-style sequences.
iter() + try/exceptYesYesMost reliable, but slower.
Check __iter__/__getitem__YesYesMay include non-iterable objects.

Examples of Iterable Objects

  • Built-in: list, str, dict, set, tuple, generator
  • Custom Classes: Objects with __iter__ or __getitem__ methods.
  • Files: Open file handles (e.g., with open(...) as f).

Non-Iterable Objects

  • Primitives: int, float, bool, None
  • Non-iterable classes: Objects without __iter__ or __getitem__.

When to Use Which?

  • Use collections.abc.Iterable for standard iterables (e.g., lists, strings).
  • Use the iter() + try/except approach for edge cases (e.g., custom sequences).
  • Avoid checking __iter__/__getitem__ directly unless necessary.

Final Recommendation

Use the iter() + try/except method for reliability across all iterable types:

def is_iterable(obj):
    try:
        iter(obj)
        return True
    except TypeError:
        return False

Leave a Reply

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