ProgrammingBackend Developer

What is an iterable object in Python and how to properly implement a custom iterable object?

Pass interviews with Hintsage AI assistant

Answer

Background: The concept of iterability appeared in Python to unify the handling of collections: lists, dictionaries, sets, etc. Any object that can be traversed using a for loop is considered iterable. This is implemented through certain magic methods.

The Problem: Python requires certain protocols for the correct functioning of loops and functions related to sequences. If the user incorrectly implements these protocols in their class, standard mechanisms (for, list(), sum(), etc.) will not work or will behave unexpectedly.

The Solution: An object is iterable if it implements the __iter__ method. An iterator is one that has the __next__ and __iter__ methods, with __iter__ returning itself. Usually, the object returned by __iter__ is an iterator, but it doesn't have to be. Example:

class MyRange: def __init__(self, start, end): self.start = start self.end = end def __iter__(self): self.current = self.start return self def __next__(self): if self.current < self.end: val = self.current self.current += 1 return val raise StopIteration for x in MyRange(1, 4): print(x) # 1, 2, 3

Key Features:

  • Iterability is determined by the presence of the __iter__ method.
  • An iterator must implement both __next__ and __iter__ (returning self).
  • Returning a new object in __iter__ is effectively implemented if multiple independent passes over the collection are needed.

Trick Questions.

Is the __next__ method mandatory for any iterable object?

No. An iterable object only requires __iter__, which returns an iterator. __next__ is only implemented by the iterator itself. For example, the list does not have a __next__ method, but it is iterable: its __iter__ returns an instance of an iterator.

lst = [1, 2, 3] print(hasattr(lst, '__next__')) # False

Can an object be an iterator by itself?

Yes, if it implements both methods — __iter__ and __next__.

Can multiple iterators with independent states be created for one collection?

Yes, if __iter__ returns a new iterator object each time.

class MyList: def __init__(self, data): self.data = data def __iter__(self): return iter(self.data)

Common Mistakes and Anti-Patterns

  • Implementing only __next__ without __iter__ (or vice versa).
  • Storing state at the class level instead of the instance level, which leads to bugs during multiple traversals.

Real-Life Example

Negative Case: An iterator class stores state (e.g., current index) at the class level instead of the instance level, causing parallel traversals to interfere with each other. Pros:

  • Less memory (only one index). Cons:
  • Errors during simultaneous iteration by two loops.

Positive Case: Each iterator stores its state in the instance created in __iter__. Pros:

  • Correct functioning of multiple iterators. Cons:
  • Slightly higher memory overhead.