iterator and iterable

iterator and iterable

What iterable and iterator?

Concept
What it is
Key Method
Both of them contain __iter__ method.
Analogy
Iterable
Any object capable of returning its members one at a time.
Implements __iter__()
In case of iterable it returns the corresponding iterator
A book full of pages.
Iterator
An object representing a stream of data; computes the next item on demand.
Implements __iter__() and __next__()
In case of iterator it returns itself
A bookmark tracking where you are in the book.
  • Iterable is an object, which one can iterate over (loop over).
    • An iterable object is an object that implements __iter__, which is expected to return an iterator object. It generates an Iterator when passed to iter() method.
    • Example: A list is iterable because we can loop over a list BUT is not an iterator.
  • Iterator is an object, which is used to iterate over an iterable object using next() method. Iterators have next() method, which returns the next item of the object, and raises a StopIteration exception when no more elements are available.

What iter() does?

iter() method returns the iterator object, it is used to convert an iterable to the iterator.

Class of an object needs a method __iter__, which returns an iterator.

What is StopIteration?

Raised by built-in function next() and an iterator's __next__() method to signal that there are no further items produced by the iterator

How for loop works?

The for loop uses this iterator to iterate over the object by using the next method. The for loop stops when next(iterator_obj) returns a StopIteration exception.

numbers = [10, 20, 30]  # List (Iterable)

# What you write:
for num in numbers:
    print(num)

# What Python actually does:
iterator = iter(numbers)  # 1. Calls numbers.__iter__() to get an iterator
while True:
    try:
        num = next(iterator)  # 2. Calls iterator.__next__() to get item
        print(num)
    except StopIteration:
        break  # 3. Signals end of stream

Example: Custom iterator

Due to the laziness of Python iterators, they are a great way to deal with infinity, i.e. iterables which can iterate for ever.

Lazy evaluation = is an evaluation strategy which delays the evaluation of an expression until its value is really needed

# To see if the object has this method iter() we can use the below function.
ls = ['hello','bye']
print(dir(ls)) # [..., '__iter__', ...]
# As you can see has the iter() that's mean that is a iterable object, but doesn't contain the next() method which is a feature of the iterator object.

Generators (The Easier Way)

Generators are the most pythonic way to create iterators. Using the yield keyword automatically manages the state and raises StopIteration for you.

def count_up_to(max_val):
  count = 1
  while count <= max_val:
    yield count
    count += 1

# Usage:
gen = count_up_to(3)  # Returns a generator object (which is an iterator)
print(next(gen))  # 1
print(next(gen))  # 2

Built-in Helper Functions

Python provides built-in tools in the standard library to simplify working with iterables:

  • iter(obj): Obtains an iterator from an iterable.
  • next(iterator, default): Retrieves the next item or returns the default value if exhausted.
  • itertools module: Provides functions like cycle(), chain(), and islice() for memory-efficient iteration pipelines.

References

SuperMade with Super