SwadhyAI Notes

All Python notes

Python Iterators 🔄

Under the Hood of Loops

An iterator is an object that contains a countable number of values. Technically, in Python, an iterator is an object which implements the iterator protocol, which consists of the methods __iter__() and __next__().

🎵 Analogy: The Music Playlist

Think of an iterator as a music playlist.
- You press "Next" (__next__()) to play the next song.
- You can only go forward, one song at a time.
- When the playlist ends, you can't press "Next" anymore (StopIteration).

✨ Iterator vs Iterable

Lists, tuples, dictionaries, and sets are all iterable objects. They are containers which you can get an iterator from.

python
mytuple = ("apple", "banana", "cherry")
myit = iter(mytuple)

print(next(myit)) # apple
print(next(myit)) # banana
print(next(myit)) # cherry

🛠️ Creating a Custom Iterator

To create an object/class as an iterator you have to implement the methods __iter__() and __next__() to your object.

python
class MyNumbers:
  def __iter__(self):
    self.a = 1
    return self

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

myclass = MyNumbers()
myiter = iter(myclass)

print(next(myiter)) # 1
print(next(myiter)) # 2

🛑 StopIteration

The example above would continue forever if you had enough next() statements, or if it was used in a for loop. To prevent the iteration to go on forever, we use the StopIteration statement.

python
class MyNumbers:
  def __iter__(self):
    self.a = 1
    return self

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

myclass = MyNumbers()
myiter = iter(myclass)

for x in myiter:
  print(x)
# Output: 1, 2, 3, 4, 5

🎯 Real-World Application: Pagination

Iterators are perfect for handling large datasets where you don't want to load everything into memory at once. You just fetch the "next" page when needed.

✨ Pro Tip: Generators

Creating iterators with classes is verbose. Python has a shortcut called Generators using the yield keyword. It does the same thing but with much less code!

python
def my_generator():
    yield 1
    yield 2
    yield 3

for x in my_generator():
    print(x)