ReviseAlgo Logo

Iterators & Generators

Iterables

Understanding iterables vs iterators — objects that can produce iterators, the iter() function, and building custom iterable collections.

Interview: Interviewers frequently ask the difference between iterables and iterators — a key Python concept.

Last Updated: June 12, 2026 8 min read

An iterable is any object that can produce an iterator via iter(). Lists, strings, dicts, sets, and tuples are all iterables. The key difference: iterables have __iter__() (which returns a new iterator), while iterators also have __next__().

Iterable vs Iterator

  • Iterable: Has __iter__() — returns a fresh iterator each time. Can be iterated multiple times.
  • Iterator: Has both __iter__() and __next__() — single-use, stateful.
  • A list is an iterable (not an iterator) — iter([1,2,3]) returns a new list_iterator each time
  • A generator is both an iterable and an iterator — it can only be consumed once

Common Iterables

  • Sequences: list, tuple, str, range
  • Collections: dict, set, frozenset
  • Files: open file objects (iterate over lines)
  • Custom: Any class that implements __iter__()

Making Custom Iterables

Implement __iter__() to return a new iterator. Use __len__() and __getitem__() for additional support:

  • __iter__() should return a new iterator each time (so the iterable is reusable)
  • __getitem__() with sequential indices also makes an object iterable (sequence protocol)
  • __len__() enables len() and helps with pre-allocation in some contexts

Interview Insight

The classic interview question: "Is a list an iterator?" Answer: No — a list is an iterable. iter(list) returns a list_iterator, which is the iterator. Lists can be iterated multiple times; iterators are consumed after one pass.

Use Cases

Custom collections — making domain objects iterable (playlists, inventories)

Data containers — wrapping lists/dicts with custom iteration behavior

API design — returning iterables from functions for flexibility

Testing — creating mock iterables for unit tests

Lazy data sources — iterables that fetch data on demand

Common Mistakes

Confusing iterables with iterators — iterables can be reused, iterators are single-pass

Returning self from __iter__ in a collection — makes it an iterator, not reusable

Not implementing __iter__ — relying only on __getitem__ is the older sequence protocol

Calling next() on an iterable directly — must call iter() first to get an iterator

Forgetting that generators are both iterables and iterators — they exhaust after one use