Bird
Raised Fist0
Pythonprogramming~10 mins

Iterator protocol in Python - Step-by-Step Execution

Choose your learning style10 modes available

Start learning this pattern below

Jump into concepts and practice - no test required

or
Recommended
Test this pattern10 questions across easy, medium, and hard to know if this pattern is strong
Concept Flow - Iterator protocol
Create iterable object
Call iter() to get iterator
Call next() on iterator
Yield next item if available
StopIteration raised when done
End
The iterator protocol means an object can be looped over by calling iter() to get an iterator, then repeatedly calling next() until no items remain.
Execution Sample
Python
numbers = [10, 20, 30]
it = iter(numbers)
print(next(it))
print(next(it))
print(next(it))
This code creates an iterator from a list and prints each item one by one using next().
Execution Table
StepActionIterator Statenext() ResultOutput
1Create list 'numbers'N/AN/AN/A
2Call iter(numbers) to get iterator 'it'it points before first elementN/AN/A
3Call next(it)it moves to first element1010
4Call next(it)it moves to second element2020
5Call next(it)it moves to third element3030
6Call next(it) againNo more elementsStopIteration raisedProgram stops if not caught
💡 StopIteration raised because iterator has no more elements
Variable Tracker
VariableStartAfter Step 2After Step 3After Step 4After Step 5After Step 6
numbers[10, 20, 30][10, 20, 30][10, 20, 30][10, 20, 30][10, 20, 30][10, 20, 30]
it (iterator position)N/ABefore first elementAt 10At 20At 30End (no more elements)
Key Moments - 3 Insights
Why does calling next() after the last item cause an error?
Because the iterator has no more items, next() raises StopIteration to signal the end (see step 6 in execution_table).
Is the original list 'numbers' changed by iter() or next()?
No, the list stays the same; only the iterator's position changes (see variable_tracker for 'numbers' and 'it').
What does iter() actually do?
iter() returns an iterator object that keeps track of the current position for next() calls (step 2 in execution_table).
Visual Quiz - 3 Questions
Test your understanding
Look at the execution_table, what is the output of next(it) at step 4?
A20
B30
C10
DStopIteration
💡 Hint
Check the 'next() Result' column at step 4 in execution_table.
At which step does the iterator reach the end and raise StopIteration?
AStep 3
BStep 5
CStep 6
DStep 2
💡 Hint
Look for 'StopIteration raised' in the 'next() Result' column.
If we call next(it) only twice, what will be the iterator's position after that?
AAt 10
BAt 20
CBefore first element
DAt 30
💡 Hint
Check variable_tracker for 'it' after step 4.
Concept Snapshot
Iterator protocol in Python:
- Use iter(obj) to get an iterator.
- Use next(iterator) to get next item.
- When no items left, next() raises StopIteration.
- Original object stays unchanged.
- Enables looping over objects step-by-step.
Full Transcript
The iterator protocol in Python allows an object to be looped over by first calling iter() to get an iterator. This iterator remembers the current position. Each call to next() returns the next item and moves the position forward. When there are no more items, next() raises StopIteration to signal the end. The original object does not change during this process. This protocol is how Python loops like for work behind the scenes.

Practice

(1/5)
1. What does the __iter__ method do in the iterator protocol?
easy
A. Returns the iterator object itself
B. Returns the next item in the sequence
C. Stops the iteration
D. Creates a list from the iterable

Solution

  1. Step 1: Understand the role of __iter__

    The __iter__ method is called to get an iterator object from an iterable.
  2. Step 2: Identify what __iter__ returns

    It returns the iterator object itself, which has the __next__ method to fetch items.
  3. Final Answer:

    Returns the iterator object itself -> Option A
  4. Quick Check:

    __iter__ returns iterator object [OK]
Hint: Remember: __iter__ returns the iterator itself [OK]
Common Mistakes:
  • Confusing __iter__ with __next__
  • Thinking __iter__ returns the next item
  • Assuming __iter__ stops iteration
2. Which of the following is the correct way to define an iterator class in Python?
easy
A. class MyIter: def __next__(self): pass
B. class MyIter: def next(self): pass
C. class MyIter: def __iter__(self): return self def __next__(self): pass
D. class MyIter: def iter(self): return self

Solution

  1. Step 1: Check required methods for iterator

    An iterator class must have __iter__ returning self and __next__ to get next item.
  2. Step 2: Match methods with options

    class MyIter: def __iter__(self): return self def __next__(self): pass correctly defines both __iter__ and __next__ methods.
  3. Final Answer:

    Defines both __iter__ and __next__ methods -> Option C
  4. Quick Check:

    Iterator class needs __iter__ and __next__ [OK]
Hint: Iterator class must have __iter__ and __next__ methods [OK]
Common Mistakes:
  • Using next() instead of __next__()
  • Missing __iter__ method
  • Defining iter() instead of __iter__()
3. What will be the output of this code?
class Count:
    def __init__(self, limit):
        self.limit = limit
        self.num = 0
    def __iter__(self):
        return self
    def __next__(self):
        if self.num < self.limit:
            self.num += 1
            return self.num
        else:
            raise StopIteration

for i in Count(3):
    print(i, end=' ')
medium
A. Error: StopIteration not handled
B. 0 1 2
C. 1 2 3 4
D. 1 2 3

Solution

  1. Step 1: Understand the iterator behavior

    The Count class starts num at 0 and returns num+1 until it reaches limit 3.
  2. Step 2: Trace the loop output

    Loop prints 1, 2, 3 then raises StopIteration to end loop.
  3. Final Answer:

    1 2 3 -> Option D
  4. Quick Check:

    Count(3) yields 1 to 3 [OK]
Hint: StopIteration ends loop; count from 1 to limit [OK]
Common Mistakes:
  • Starting count from 0 instead of 1
  • Expecting 4 as output
  • Thinking StopIteration causes error
4. Identify the error in this iterator implementation:
class MyIter:
    def __init__(self):
        self.data = [1, 2, 3]
        self.index = 0
    def __iter__(self):
        return self
    def __next__(self):
        if self.index <= len(self.data):
            result = self.data[self.index]
            self.index += 1
            return result
        else:
            raise StopIteration
medium
A. The condition should be self.index < len(self.data)
B. Missing return self in __iter__
C. Should raise StopIteration before returning result
D. Index should start at 1, not 0

Solution

  1. Step 1: Analyze the index condition

    Index goes from 0 to len(data)-1. Using <= allows index == len(data), causing IndexError.
  2. Step 2: Correct the condition

    Change condition to self.index < len(self.data) to avoid out-of-range access.
  3. Final Answer:

    The condition should be self.index < len(self.data) -> Option A
  4. Quick Check:

    Index must be less than length to avoid error [OK]
Hint: Use < to avoid index out of range errors [OK]
Common Mistakes:
  • Using <= instead of < in index check
  • Forgetting to return self in __iter__
  • Starting index at 1 instead of 0
5. You want to create a custom iterator that returns only even numbers from 0 up to a given limit (exclusive). Which implementation correctly follows the iterator protocol and filters evens?
class EvenIterator:
    def __init__(self, limit):
        self.limit = limit
        self.current = 0
    def __iter__(self):
        return self
    def __next__(self):
        while self.current < self.limit:
            val = self.current
            self.current += 1
            if val % 2 == 0:
                return val
        raise StopIteration
hard
A. Fails because __iter__ should return a new object each time
B. Correct implementation returning even numbers up to limit
C. Incorrect because it returns odd numbers instead
D. Raises StopIteration too early, missing some evens

Solution

  1. Step 1: Check iterator protocol methods

    Class defines __iter__ returning self and __next__ with loop and StopIteration.
  2. Step 2: Verify filtering logic

    Inside __next__, it loops until limit, returns only even values, skipping odds.
  3. Final Answer:

    Correct implementation returning even numbers up to limit -> Option B
  4. Quick Check:

    Iterator filters evens correctly [OK]
Hint: Use while loop inside __next__ to skip unwanted items [OK]
Common Mistakes:
  • Returning odd numbers by mistake
  • Not raising StopIteration when done
  • Returning new iterator in __iter__ each time