techmore.in

Python - Iterators

What Are Iterators?

An iterator is an object that can be iterated upon, meaning you can traverse through all the values. Technically, an iterator is an object which implements the __iter__() and __next__() methods.

Using iter() and next()

python
# Creating an iterator from a list
numbers = [1, 2, 3]
it = iter(numbers)

print(next(it))  # 1
print(next(it))  # 2
print(next(it))  # 3

Custom Iterator Class

You can create your own iterator by defining a class with __iter__() and __next__() methods.

python
class Counter:
    def __init__(self, limit):
        self.limit = limit
        self.count = 0

    def __iter__(self):
        return self

    def __next__(self):
        if self.count < self.limit:
            self.count += 1
            return self.count
        else:
            raise StopIteration

for num in Counter(3):
    print(num)

What Are Generators?

Generators are a simple and concise way to create iterators using functions and the yield keyword. They allow you to iterate lazily (one item at a time) without storing all values in memory.

Creating a Generator with yield

python
# Generator function
def countdown(n):
    while n > 0:
        yield n
        n -= 1

for val in countdown(3):
    print(val)

Generator Expressions

Like list comprehensions but using () instead of [], generator expressions are memory-efficient and lazy.

python
# Generator expression
squares = (x*x for x in range(5))

for s in squares:
    print(s)

Why Use Iterators and Generators?

  • Memory Efficiency: Only one item is in memory at a time.
  • Performance: Lazily evaluated, improving speed with large data.
  • Cleaner Code: Especially with yield or generator expressions.

When to Use?

  • Working with large datasets or streams
  • Implementing pipelines or custom data flows
  • Lazy evaluation required

Pros and Cons

  • Pros: Efficient, simple syntax, useful for streams
  • Cons: Can only be iterated once, less intuitive debugging