
Difference Between Iterable and Iterator Objects
While iterable and iterator objects are closely related, they are not the same thing. However, they often work together in Python.
- Iterable
An object is considered iterable if you can loop over its elements one by one. An object qualifies as iterable if it implements the special method `__iter__()`, which returns an iterator.Common examples of iterable objects include lists, tuples, strings, dictionaries, and sets. When you pass an iterable to a `for` loop, Python automatically calls the object’s `__iter__()` method to obtain an iterator.
- Iterator
An iterator is an object that keeps track of its position as it goes through a sequence of elements. It implements the special methods `__iter__()` and `__next__()`.- The `__iter__()` method returns the iterator object itself, allowing it to be used in a `for` loop or with the `next()` function.
- The `__next__()` method returns the next element in the sequence. When no more elements are left, it raises the `StopIteration` exception to signal the end of the iteration.
So, what's the difference?
When you call `iter()` on an iterable object, Python invokes the object’s `__iter__()` method, which returns an iterator.
In other words, an iterable provides an iterator.
For instance, a list (`[1, 2, 3]`) is an iterable object. When you call `iter()` on the list, it returns an iterator that allows you to traverse the list’s elements one by one.
On the other hand, an iterator is also an iterable because it implements `__iter__()` which returns itself.
The key difference is that you can also call the `__next__()` method on an iterator to manually step through the elements.
It’s important to note that iteration over an iterator is consumable: once an element has been retrieved from the iterator, it cannot be accessed again unless the iterator is recreated.
Example
Imagine you have a list of numbers:
numbers = [1, 2, 3, 4, 5]
This is an iterable object.
So, you can use a `for` loop to read each element one after another.
for item in numbers:
print(item)
1
2
3
4
5
Note: You can’t use the next() function directly on an iterable object because it doesn’t implement the '__next__()' method.
If you call the `iter()` function on the list, you’ll get an iterator object:
iterator = iter(numbers)
This is now an iterator object.
This means you can use the `next()` function to retrieve elements one by one:
print(next(iterator))
1
If you keep calling `next()` on the iterator, you’ll continue traversing through the list’s elements.
print(next(iterator))
2
When there are no more elements, a `StopIteration` exception will be raised.
Since an iterator object is also iterable, you can alternatively loop through it using a `for` loop.
for item in iterator:
print(item)
1
2
3
4
5
In summary, an iterable is an object from which you can obtain an iterator, while an iterator is the object that enables you to traverse the elements of an iterable.
Though they might seem similar, they serve distinct roles in Python's iteration protocol.