L2 · Working engineerPython internals~6 min · 5 tests#61

Build a Custom Iterator (__iter__, __next__)

Implement Python's iterator protocol with __iter__ and __next__, raising StopIteration at the end. Your class then works in for-loops and list().

The problem

Write a class MyIterator(data) that walks a list using the iterator protocol:

  • __iter__ returns the iterator itself
  • __next__ returns the next item, and raises StopIteration when finished

list(MyIterator([10, 20, 30])) → [10, 20, 30].

Examples

  1. Example 1

    Input

    list(MyIterator([10, 20, 30]))

    Expected output

    [10, 20, 30]
  2. Example 2

    Input

    (lambda it: iter(it) is it)(MyIterator([1]))

    Expected output

    True

+ 3 hidden tests on Submit — StopIteration at the end.

Edge cases to ask about

  • Empty data
  • Exhaustion
  • Reuse after exhaustion

Hints

0/3

    How an interviewer scores this

    0/9
    Python 3.13 · MyIterator
    ⌘/Ctrl + Enter runs the examples

    Your code runs in real CPython inside your browser — nothing is sent anywhere. The first run downloads the interpreter (about 6 MB, once). Your code is saved on this device as you type.

    Complexity Lab

    What does this cost as n grows?

    Interviewers score the analysis as much as the code. Commit to an answer first — then check it, and read why.

    Time complexity of the optimal solution
    Space complexity (extra memory)

    Pick both to reveal the answer.

    From brute force to optimal

    The progression an interviewer wants to hear, one step at a time.

    ApproachTimeSpaceIdea
    Iterator protocolO(1) per itemO(1)for-loops call iter() then next() until StopIteration.
    Walkthrough of the optimal approach (try it yourself first)

    A for loop calls iter(obj) once, then next() until StopIteration. An iterator returns self from __iter__ and keeps its position.

    An iterable (like a list) returns a new iterator from __iter__, which is why you can loop over a list twice but this iterator only once. A generator function is the shortcut that writes this class for you.

    Complexity: O(1) time, O(1) space. Each next() does constant work and the iterator stores one index.

    Reveal the reference solution
    class MyIterator:
        def __init__(self, data):
            self.data = data
            self.index = 0
    
        def __iter__(self):
            return self
    
        def __next__(self):
            if self.index >= len(self.data):
                raise StopIteration
            value = self.data[self.index]
            self.index += 1
            return value

    Follow-ups interviewers ask

    • Make it re-iterable (an iterable that returns a fresh iterator).
    • Rewrite it as a generator.

    Frequently asked interview questions

    Core interview concepts, complexities, and follow-ups scored by hiring teams.

    What is the time complexity of Build a Custom Iterator (__iter__, __next__) in Python?

    The optimal solution runs in O(1) time and O(1) auxiliary space. Each next() does constant work and the iterator stores one index.

    What follow-up questions do interviewers ask about Build a Custom Iterator (__iter__, __next__)?

    Make it re-iterable (an iterable that returns a fresh iterator). Rewrite it as a generator.