What is the difference between iterator and iterable in Python?

  • Is an iterator, an iterable too?
  • How can an iterable be converter to an iterator?

In Python, iterable is anything you can loop over with a for loop, such as a string, a list, a file etc.

In Python, an iterator is an object representing a stream of data. It returns the data one element at a time. A Python iterator supports __next__() method that takes no arguments and always returns the next element of the stream. If there are no more elements left, __next__() must raise the StopIteration exception. One can also write an iterator that produces an infinite stream of data.


Note that every iterator is also an iterable, but not every iterable is an iterator. For example, a list is iterable but a list is not an iterator.


An iterator can be created from an iterable by using the function iter(). The built-in iter() function takes an arbitrary object and tries to return an iterator that will return the object’s contents or elements, raising TypeError if the object doesn’t support iteration. To make this possible, the class of an object needs either a method __iter__, which returns an iterator, or a __getitem__ method with sequential indexes starting with 0.


When a for loop is executed, for statement calls iter() on the object, which it is supposed to loop over. If this call is successful, the iter call will return an iterator object that defines the method __next__(), which accesses elements of the object one at a time. The __next__() method will raise a StopIteration exception, if there are no further elements available. The for loop will terminate as soon as it catches a StopIteration exception.


It should be noted that string, lists, tuples, ranges, dictionaries and sets support iterators. File objects also support iteration.


Let us look at the following sets of code to understand iterators and iterables:


1: Iterators and iterables can be iterated using for loop.

>>> iterable = 'foo'
>>> iterator = iter(iterable)
>>> print(iterable)
foo

>>> print(iterator)
<str_iterator object at 0x7fceb55add50>

>>> for i in iterable:
...     print(i)
f
o
o

>>> for i in iterable:
...      print(i)
f
o
o



2: Iterators are also iterable

As mentioned above, an iterator can be created from an iterable by using the function iter() . Similarly, we can call iter() function on the iterator itself. It will return the iterator object itself.

>>> iterable = 'foo'
>>> iterator1 = iter(iterable)

>>> print(iterator1)
>>> print(type(iterator1))
<str_iterator object at 0x7fceb5510b50>
<class 'str_iterator'>

>>> iterator2 = iter(iterator1)
>>> print(iterator2)
>>> print(type(iterator2))
<str_iterator object at 0x7fceb5510b50>
<class 'str_iterator'>

>>> print(iterator1 == iterator2)
True



For more, check out the following links:
https://docs.python.org/3/howto/functional.html#iterators
https://docs.python.org/3.8/glossary.html#term-iterator