Iterators

Understanding Iterators in Python

In Python, iterators are powerful tools that allow you to traverse through a sequence of values in a controlled manner. An iterator is essentially an object that can be iterated upon, meaning you can access its elements one by one.

What is an Iterator?

An iterator is an object that follows the iterator protocol, which requires the implementation of two key methods:

  • __iter__() – Returns the iterator object itself.
  • __next__() – Returns the next value in the sequence.

In Python, common iterable objects include lists, tuples, dictionaries, and sets. These iterable containers provide the iter() method, which returns an iterator for the object.

Iterables vs Iterators

While iterables are objects that can return an iterator (like lists, tuples, and strings), iterators are objects that implement the iterator protocol. Here’s how you can work with iterables and iterators:

Example: Iterating Through a Tuple

mytuple = ("book1", "book2", "book3")
myit = iter(mytuple)

print(next(myit))  # Outputs: book1
print(next(myit))  # Outputs: book2
print(next(myit))  # Outputs: book3

Example: Iterating Through a String

mystr = "library"
myit = iter(mystr)

print(next(myit))  # Outputs: l
print(next(myit))  # Outputs: i
print(next(myit))  # Outputs: b
print(next(myit))  # Outputs: r
print(next(myit))  # Outputs: a
print(next(myit))  # Outputs: r

Looping Through an Iterator

You can also use a for loop to iterate over an iterable object. The for loop automatically creates an iterator and calls __next__() until all values are exhausted.
<

Example: Using a For Loop with a Tuple

mytuple = ("book1", "book2", "book3")  # Creating a tuple with three books

for book in mytuple:  # Iterating over each item in the tuple
    print(book)  # Output each book title
    # Expected output:
    # book1
    # book2
    # book3

Example: Using a For Loop with a String

mystr = "library"
for char in mystr:
  print(char)

Creating Your Own Iterator

To define a custom iterator, you need to create a class that implements both __iter__() and __next__(). Here’s a basic example of how to create an iterator that returns numbers sequentially:

Example: Custom Iterator Class

class NumberIterator:
  def __iter__(self):
    self.current = 1
    return self

  def __next__(self):
    number = self.current
    self.current += 1
    return number

numbers = NumberIterator()
number_iter = iter(numbers)

print(next(number_iter))  # Outputs: 1
print(next(number_iter))  # Outputs: 2
print(next(number_iter))  # Outputs: 3
print(next(number_iter))  # Outputs: 4
print(next(number_iter))  # Outputs: 5

Handling StopIteration

To prevent an iterator from running indefinitely, implement a condition in __next__() to raise a StopIteration exception when a certain condition is met. This tells the iteration to stop.

Example: Iterator with StopIteration

class LimitedNumberIterator:
  def __iter__(self):
    self.current = 1
    return self

  def __next__(self):
    if self.current <= 20:
      number = self.current
      self.current += 1
      return number
    else:
      raise StopIteration

limited_numbers = LimitedNumberIterator()
limited_number_iter = iter(limited_numbers)

for number in limited_number_iter:
  print(number)

Leave a Comment