Iterators in Python

Iterators in Python

This article explains iterators in Python.

YouTube Video

Iterators in Python

Overview

In Python, an iterator is a fundamental mechanism for processing elements of collections such as lists, tuples, and dictionaries one by one.

What is an Iterator?

An iterator is an object that can return elements one at a time. In Python, an object is considered an iterator if it meets the following two conditions:.

  • It has an __iter__() method that returns itself.
  • It has a __next__() method that returns the next element. It raises StopIteration when there are no more elements.
1iterator = iter([1, 2, 3])
2print(next(iterator))  # 1
3print(next(iterator))  # 2
4print(next(iterator))  # 3
5# print(next(iterator))  # StopIteration occurs
  • In this code, the iter() function is used to convert a list into an iterator, and the next() function is used to retrieve and display each element one by one.

Difference from Iterable

An iterable is an object that implements the __iter__() method and can be used in a for loop. Lists and tuples are examples of iterables.

1nums = [10, 20, 30]
2it = iter(nums)  # Get an iterator from the iterable
3print(next(it))  # 10
  • This code is an example of obtaining an iterator from an iterable such as a list and retrieving elements in order using next().

How to check:

1from collections.abc import Iterable, Iterator
2
3nums = [10, 20, 30]
4it = iter(nums)
5
6print(isinstance(nums, Iterable))  # True
7print(isinstance(nums, Iterator))  # False
8print(isinstance(it, Iterator))    # True
  • This code confirms that nums is an iterable but not an iterator, while it, obtained using iter(nums), is an iterator.

Relationship Between for Loops and Iterators

A for loop in Python internally works as follows:.

1nums = [1, 2, 3]
2iterator = iter(nums)
3while True:
4    try:
5        value = next(iterator)
6        print(value)
7    except StopIteration:
8        break
  • As shown, the for loop implicitly uses an iterator to perform iteration.

Creating a Custom Iterator

You can create a custom iterator using a class.

 1class Countdown:
 2    def __init__(self, start):
 3        self.current = start
 4
 5    def __iter__(self):
 6        return self
 7
 8    def __next__(self):
 9        if self.current <= 0:
10            raise StopIteration
11        value = self.current
12        self.current -= 1
13        return value
14
15for num in Countdown(3):
16    print(num)  # 3, 2, 1
  • This code defines a custom iterator that counts down using the Countdown class and prints numbers from 3 to 1 using a for loop.

Difference Between Iterators and Generators, and When to Use Each

Generators provide functionality similar to iterators. They allow you to define iterators more concisely.

1def countdown(n):
2    while n > 0:
3        yield n
4        n -= 1
5
6for i in countdown(3):
7    print(i)  # 3, 2, 1
  • This code defines a generator function that counts down using yield, and prints numbers from 3 to 1 using a for loop.

Differences Between Iterators (Class) and Generators (Function)

There are the following differences between iterators (classes) and generators (functions):.

Feature Iterator (class) Generator (function)
Definition __iter__() + __next__() Function using yield
State Management Manual attribute handling required Automatically maintains state
Readability Can become complex Simple and clear
  • Difference in How They Are Defined An iterator is defined by manually writing two methods: __iter__() and __next__(). In contrast, a generator is just a function that uses the yield keyword, making the code much simpler.

  • Difference in State Management With an iterator, you must manage the current state and progress manually using variables. Generators, however, automatically retain their state internally in Python, reducing manual effort.

  • Code Readability Iterators tend to become complex because they require multiple methods and manual state management. In contrast, generators use simple syntax, making them easier to understand even for beginners.

Standard Library for Using Iterators: itertools

itertools, a standard Python library, provides powerful tools for working with iterators.

1import itertools
2
3for x in itertools.count(10, 2):  # 10, 12, 14, ...
4    if x > 20:
5        break
6    print(x)
  • It also includes many other functions such as cycle, repeat, chain, islice, and tee.

Use Cases for Iterators

Use cases for iterators include the following:.

  • Processing File Lines: Read lines one by one from a file as an iterator.
  • Memory-Efficient Processing: Process large amounts of data sequentially.
  • Representing Infinite Sequences: Use functions like itertools.count().

Summary

  • An iterator is an object that can retrieve the next value sequentially.
  • You can create a custom iterator by defining __iter__() and __next__().
  • They are handled automatically via for loops or the next() function.
  • Using generators or itertools enables more efficient processing.

By using iterators, you can process large volumes of data sequentially in a memory-efficient way, allowing for controlled state management and improved program performance.

You can follow along with the above article using Visual Studio Code on our YouTube channel. Please also check out the YouTube channel.

YouTube Video