Nearby lessons

113 of 159

Python - Iterators

📌 What You Will Learn
  • Understand what an iterator is
  • Know the difference between an iterable and an iterator
  • Use the iterator protocol with __iter__() and __next__()
  • Understand how the for loop uses iter() and next() internally
  • Create a custom iterator class

What is an Iterator?

An iterator is an object that produces a sequence of values one at a time.

Instead of storing the entire sequence in memory, an iterator remembers its current position and produces the next value only when asked.

Iterators are the mechanism Python uses internally whenever a sequence is looped over.

Iterable vs Iterator

These two terms are often confused, but they are different.

Feature Iterable Iterator
Meaning An object that can be iterated over An object that produces the values
Examples List, tuple, string, dictionary, set Result of iter(), generator, file object
Key Method __iter__() __next__()
Can Be Reused Yes No, an iterator is exhausted after its values end

The Iterator Protocol

In Python, any object is an iterator if it implements two methods. Together these two methods are called the Iterator Protocol.

  • __iter__() returns the iterator object itself.
  • __next__() returns the next value, and raises StopIteration when no more values remain.

The iter() and next() Functions

Python provides two built-in functions to work with iterators.

  • iter(iterable) converts an iterable into an iterator.
  • next(iterator) fetches the next value from the iterator.

Every call to next() advances the iterator by one position.

Program: Converting a List into an Iterator

🐍Code Cell
1l = [10, 20, 30]
2 
3i = iter(l)
4 
5print(next(i))
6print(next(i))
7print(next(i))
Output
10
20
30

Explanation

Here, iter(l) converts the list l into an iterator i.

Each call to next(i) returns the next element of the list.

What is StopIteration?

When an iterator has no more values to produce, calling next() raises a StopIteration exception.

This exception signals that the iteration is complete.

🐍Code Cell
1l = [10, 20]
2 
3i = iter(l)
4 
5print(next(i))
6print(next(i))
7print(next(i))
Output
10
20
Traceback (most recent call last):
  File "test.py", line 7, in 
    print(next(i))
StopIteration

How the for Loop Works Internally

When we write a for loop, Python performs the following steps internally:

  1. It calls iter() on the iterable to obtain an iterator.
  2. It repeatedly calls next() on the iterator.
  3. When StopIteration is raised, the loop ends.

So a for loop over a list is internally an iterator using next().

Program: for Loop Internals

🐍Code Cell
1l = [10, 20, 30]
2 
3i = iter(l)
4 
5while True:
6 try:
7 x = next(i)
8 print(x)
9 except StopIteration:
10 break
Output
10
20
30

Explanation

This program manually replicates what a for loop does:

  • iter(l) creates the iterator.
  • The while True loop keeps calling next(i).
  • When StopIteration is raised, break ends the loop.

Creating a Custom Iterator

We can create our own iterator by defining a class that implements both __iter__() and __next__().

The following class creates an iterator that produces the first n natural numbers.

🐍Code Cell
1class MyNumbers:
2 
3 def __init__(self, n):
4 self.n = n
5 self.current = 0
6 
7 def __iter__(self):
8 return self
9 
10 def __next__(self):
11 if self.current >= self.n:
12 raise StopIteration
13 self.current += 1
14 return self.current
15 
16 
17nums = MyNumbers(5)
18 
19for x in nums:
20 print(x)
Output
1
2
3
4
5

Explanation

  • __init__() stores the limit n and initializes current to 0.
  • __iter__() returns self, which is the iterator itself.
  • __next__() raises StopIteration when the limit is reached, otherwise it returns the next number.
  • The for loop works because the object implements the iterator protocol.

Advantages of Iterators

  • Values are produced one at a time instead of storing the whole sequence.
  • Very memory efficient for large sequences.
  • They provide a uniform way to loop over any sequence.
  • They are lazy: values are created only when requested.
📝 Key Takeaways
  • An iterator produces values one at a time instead of storing all of them in memory
  • The iterator protocol uses __iter__() and __next__()
  • iter() converts an iterable into an iterator, and next() fetches the next value
  • The for loop calls iter() first, then next() repeatedly until StopIteration is raised
  • Custom iterators are created by defining __iter__() and __next__() in a class

🧠 Test Your Knowledge

10 Questions
Progress: 0 / 10