A blog about C#, Python, Azure and full stack development

What are Iterators in Python?

Python is a versatile language with a great deal of built-in functionality. A core concept in Python is iterables. An iterable is any Python object capable of returning its members one at a time, permitting it to be iterated over in a for-loop. Familiar examples of iterables include lists, tuples, and strings.

Key Takeaways

  • A Python iterator is an object that contains a countable number of values and can be iterated upon.
  • Iterables are objects from which you can get an iterator.
  • The iter() method is used to get an iterator from an iterable.
  • Strings, lists, tuples, and dictionaries are common examples of iterables in Python.
  • Custom iterators can be created using Python classes by implementing the __iter__() and __next__() methods.

Python Iterators

An iterator, as defined by W3Schools, is an object that contains a countable number of values. This means you can traverse through all these values, one by one. In Python, an iterator is technically an object that implements the iterator protocol. This protocol consists of the methods __iter__() and __next__().

Iterator vs Iterable

While the terms “iterator” and “iterable” might sound similar, but they refer to different concepts:

  • Iterable: An object that will return an iterator when the iter() method is called on it. Examples of iterables include lists, tuples, dictionaries, and sets. These are containers from which you can get an iterator. For instance, when you have a tuple like ("apple", "banana", "cherry"), you can obtain an iterator using the iter() method and then retrieve each item using the next() method. More on this can be found here.
  • Iterator: An object that keeps state and produces the next value when you call next() on it. It follows the iterator protocol which requires the __iter__() and __next__() methods to be defined.

Looping Through an Iterator

Iterators can be looped through using a for loop. When you use a for loop to go through an iterable, Python internally creates an iterator object and executes the next() method for each loop. This means you can iterate over the values of a tuple or the characters of a string without explicitly retrieving each item with next(). This behavior is explained at length here.

Creating an Iterator

To make an object or class work as an iterator, you need to implement two methods in the object/class, __iter__() and __next__(). The __iter__() method does the initializing and must always return the iterator object itself. The __next__() method allows you to perform operations but must return the next item in the sequence.

Creating Custom Iterators

While Python provides a range of built-in iterables, often there might be situations where you need a custom iterator. Creating a custom iterator in Python requires the implementation of two key methods: __iter__() and __next__().

The __iter__() method is used for initialization and must return the iterator object itself. On the other hand, the __next__() method returns the next item in the sequence. If there are no more items to return, it should raise the StopIteration exception.

Here’s an example of a custom iterator that returns numbers starting from 1 and increments by one:

class MyNumbers: 
  def __iter__(self): 
    self.a = 1 
    return self 
  def __next__(self): 
    x = self.a 
    self.a += 1 
    return x

You can find more details on creating custom iterators here.

Handling Infinite Iterators

One challenge with iterators is that they can potentially run indefinitely if not handled correctly. For example, the custom iterator mentioned above will keep returning numbers indefinitely. To prevent infinite loops, the StopIteration exception can be used.

The StopIteration exception signals the end of the iteration. In the context of our example, we can modify the __next__() method to raise this exception after a certain number of iterations:

def __next__(self): 
  if self.a <= 20: 
    x = self.a 
    self.a += 1 
    return x 
    raise StopIteration

This modification ensures that the iterator stops after 20 iterations.

Frequently Asked Questions

  1. What’s the difference between an iterable and an iterator?
    • An iterable is an object that can return an iterator, while an iterator is an object that keeps track of its current state and produces the next value when next() is called on it.
  2. Can Python use strings as iterables?
    • Yes, strings are iterable objects in Python. You can loop through each character of a string using a for loop or retrieve characters using an iterator.
  3. How do I create a custom iterator in Python?
    • To create a custom iterator, you need to define a class that implements the __iter__() and __next__() methods. The __iter__() method initializes the iterator, and the __next__() method returns the next item in the sequence.