w3resource

Python Iterators: Creating and Using Iterators

Introduction to Python Iterators

In Python, an iterator is an object that can be iterated (looped) upon. An iterator returns one element at a time from a sequence, like a list, tuple, or string. Understanding iterators and how to create them is essential for writing efficient and Pythonic code.

This tutorial focuses on creating and using “iterators” through examples, with explanations provided after each example.

Example 1: Using Built-In Iterators

Python has several built-in data types that support iteration, such as lists, tuples, strings, and dictionaries. These objects are iterable, meaning they can return an iterator using the iter() function.

This example demonstrates how to convert a list into an iterator and manually iterate through it using the next() function. It highlights the basics of using Python’s built-in iterators.

Code:

# A list of numbers
numbers = [1, 2, 3, 4, 5]

# Get an iterator from the list
numbers_iter = iter(numbers)

# Iterate through the iterator using the next() function
print(next(numbers_iter))  # Output: 1
print(next(numbers_iter))  # Output: 2
print(next(numbers_iter))  # Output: 3
print(next(numbers_iter))  # Output: 4
print(next(numbers_iter))  # Output: 5

# If we call next() again, it will raise StopIteration
# print(next(numbers_iter))  # Uncommenting this line will raise StopIteration

Explanation:

  • 'iter()' Function: Converts an iterable (like a list) into an iterator.
  • 'next()' Function: Retrieves the next item from the iterator.
  • StopIteration: When the iterator is exhausted (no more items), calling 'next()' raises a 'StopIteration' exception.

Example 2: Creating a Custom Iterator

To create a custom iterator, you need to define a class that implements two methods: '__iter__()' and '__next__()'.

This example demonstrates how to create a custom iterator that generates the first n even numbers. The iterator is implemented using the '__iter__()' and '__next__()' methods.

Code:

# Custom iterator that returns the first n even numbers
class EvenNumbers:
    def __init__(self, max):
        self.max = max  # Maximum number of even numbers
        self.num = 0    # Start with 0

    def __iter__(self):
        return self  # Returning the iterator object itself

    def __next__(self):
        if self.num <= self.max:
            result = self.num
            self.num += 2  # Increment by 2 for even numbers
            return result
        else:
            raise StopIteration  # Stop iteration when max is reached

# Creating an instance of the custom iterator
even_numbers = EvenNumbers(10)

# Iterating through the custom iterator
for num in even_numbers:
    print(num)

Output:

0
2
4
6
8
10

Explanation:

Custom Iterator (EvenNumbers):

  • The '__iter__()' method returns the iterator object itself.
  • The '__next__()' method defines the logic for iteration. It returns even numbers and raises StopIteration when the limit is reached.

Example 3: Using Iterators with for Loops

Python's 'for' loop automatically handles iterators, making it easier to iterate over sequences without explicitly calling next().

This example shows how Python’s ‘for’ loop simplifies iteration by automatically handling the underlying iterator. It is the preferred method for iterating over sequences in Python.

Code:

# A list of colors
colors = ["Red", "Green", "Blue"]

# Using a for loop to iterate over the list
for color in colors:
    print(color)

Output:

Red
Green
Blue

Explanation:

for Loop:

  • The for loop automatically converts the list into an iterator and iterates over it.
  • This is the most common way to use iterators in Python because it is simple and concise.

Example 4: Creating an Infinite Iterator

An infinite iterator generates an unending sequence of values. To stop the iteration, you must use a break condition.

This example demonstrates how to create an infinite 'iterator' that generates natural numbers. It also shows how to use a break condition within a 'for' loop to control the iteration.

Code:

# Custom infinite iterator that generates natural numbers
class InfiniteNumbers:
    def __init__(self):
        self.num = 1  # Start with 1

    def __iter__(self):
        return self

    def __next__(self):
        result = self.num
        self.num += 1  # Increment by 1
        return result

# Creating an instance of the infinite iterator
infinite_numbers = InfiniteNumbers()

# Using a for loop with a break condition
for number in infinite_numbers:
    if number > 5:  # Breaking the loop after 5 numbers
        break
    print(number)

Output:

1
2
3
4
5

Explanation:

Infinite Iterator ('InfiniteNumbers'):

  • The iterator generates an unending sequence of natural numbers.
  • The 'for' loop includes a break condition ('if number > 5') to stop the iteration after 5 numbers.

Example 5: Combining Iterators Using itertools

Python's 'itertools' module provides powerful tools for creating and manipulating iterators.

This example illustrates how to use the 'itertools.chain()' function to combine multiple iterators into one. It highlights the power and flexibility of Python's 'itertools' module.

Code:

import itertools
# Two lists to combine
list1 = [1, 2, 3]
list2 = [4, 5, 6]
# Using itertools.chain() to combine the iterators
combined = itertools.chain(list1, list2)

# Iterating through the combined iterator
for item in combined:
    print(item)

Output:

1
2
3
4
5
6

Explanation:

  • 'itertools.chain()':
    • Combines multiple iterators into a single iterator.
    • The 'for' loop iterates over the combined iterator, seamlessly moving from one list to the next.

Example 6: Creating a Generator as an Iterator

Generators are a simple way to create iterators using the 'yield' statement.

This example demonstrates how to create an iterator using a generator function. Generators provide a concise way to build iterators without the need for a class-based implementation.

Code:

# Generator function to create an iterator for squares of numbers
def square_numbers(max):
    for i in range(1, max + 1):
        yield i * i  # Yielding the square of each number

# Using the generator
squares = square_numbers(5)

# Iterating through the generator
for square in squares:
    print(square)

Output

1
4
9
16
25

Explanation:

  • Generator Function ('square_numbers'):
    • Uses 'yield' to generate a sequence of square numbers.
    • When 'yield' is called, the function’s state is saved, allowing it to resume where it left off when 'next()' is called again.

Summary:

  • Built-In Iterators: Python's built-in data types like lists, strings, and dictionaries are iterable, and their iterators can be accessed using the 'iter()' function.
  • Custom Iterators: You can create custom iterators by defining a class with '__iter__()' and '__next__()' methods.
  • Infinite Iterators: Custom iterators can generate infinite sequences; you can control the iteration using a break condition.
  • 'itertools' Module: The 'itertools' module provides advanced tools for creating and combining iterators.
  • Generators: A generator function using 'yield' is an easy and efficient way to create an iterator.


Become a Patron!

Follow us on Facebook and Twitter for latest update.