PYTHON Reference Guide
Revision Time: 3 mins

Iterators Reference

Python's iterator protocol — __iter__, __next__, iter(), next(), and lazy evaluation.

Iterator Protocol
Return: T

Any object with __iter__() and __next__() methods is an iterator.

Used In: Custom data streams, database cursor wrappers, lazy file readers.

Syntax signature:__iter__(self) -> self __next__(self) -> value # raises StopIteration when done
Code snippet:
python
class Counter:
    def __init__(self, start, stop):
        self.current = start
        self.stop = stop

    def __iter__(self):
        return self

    def __next__(self):
        if self.current >= self.stop:
            raise StopIteration
        val = self.current
        self.current += 1
        return val

for n in Counter(1, 4):
    print(n)
Expected Output:1 2 3

Time Complexity: O(1) per step

Related Methods: iter(), next()

Remember: __iter__ returns the iterator object itself (self); __next__ returns the next value or raises StopIteration.
iter() / next()
Return: iterator / T

Convert an iterable to an iterator manually and advance it step by step.

Used In: Manual stream consumption, peeking at first element without loading all.

Syntax signature:iter(iterable) / next(iterator, default=None)
Code snippet:
python
data = [10, 20, 30]
it = iter(data)
print(next(it))
print(next(it))
print(next(it, 'done'))  # exhausted, returns default
print(next(it, 'done'))
Expected Output:10 20 30 done

Time Complexity: O(1)

Common Mistakes: Calling iter() on an already-exhausted iterator does not reset it — you must create a new one.

Related Methods: __iter__, __next__

Remember: Pass a default to next() to avoid StopIteration — useful when consuming streams of unknown length.
Iterable vs Iterator
Return: N/A

Distinguish between objects you can loop over (iterable) and stateful cursor objects (iterator).

Used In: Designing reusable vs single-use data streams.

Syntax signature:iterable: has __iter__() only iterator: has __iter__() and __next__()
Code snippet:
python
lst = [1, 2, 3]
it = iter(lst)
print(hasattr(lst, '__next__'))
print(hasattr(it, '__next__'))
Expected Output:False True

Time Complexity: O(1)

Comparison:

Iterable can be looped multiple times (iter() creates a new cursor each call). Iterator is single-use — once exhausted, it cannot be reset.

Remember: Lists, tuples, dicts, and strings are iterables. Calling iter() on them returns a fresh iterator each time.
Lazy Evaluation
Return: T

Iterators compute values on demand — they don't load the entire sequence into memory.

Used In: Streaming ETL, reading large log files line by line.

Syntax signature:for item in iterator:
Code snippet:
python
for i in range(10**9):
    if i > 2:
        break
    print(i)
Expected Output:0 1 2

Time Complexity: O(1) memory

Related Methods: generator expressions

Remember: Use iterators (range, file handles, generators) for large or infinite data sequences to avoid memory exhaustion.