[Python](EN) Iterable and Iterator

Post about Iterable and Iterator


Environment and Prerequisite

  • Python


Definition of Iterable and Iterator

Iterable

  • An object capable of returning its members one at a time.
  • In document, it is written An object capable of returning its members one at a time..
  • “Examples of iterables include all sequence types (such as list, str, and tuple) and some non-sequence types like dict, file objects, and objects of any classes you define with an __iter__() method or with a __getitem__() method that implements Sequence semantics.”
  • If iterable object is passed to built-in function iter(), it returns its object’s iterator.
>>> a = [1,2,3]
>>> type(a)
<class 'list'>
>>> a_iterator = iter(a)
>>> type(a_iterator)
<class 'list_iterator'>

Iterator

  • An object representing a stream of data.
  • In document, it is written An object representing a stream of data..
  • Repeated calls to the iterator’s __next__() method return successive items in the stream. It raise StopIteration exception if there is no more data.
  • Iterator has __iter__() method which returns iterator itself so iterator is also iterable.
>>> a = [1,2,3]
>>> type(a)
<class 'list'>
>>> a_iterator = iter(a)
>>> type(a_iterator)
<class 'list_iterator'>
>>> dir(a_iterator)
['__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__length_hint__', '__lt__', '__ne__', '__new__', '__next__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setstate__', '__sizeof__', '__str__', '__subclasshook__']


Iterator Types

Iterator Protocol

  • Python supports iteration concept. This is implemented by below two methods(iterator.__iter__() and iterator.__next__()) and these are used to allow user-defined classes to support iteration.
  • Document only tells about container but it looks it supports user-defined classes.
  • The iterator objects themselves are required to support the following two methods, which together form the iterator protocol.

iterator.__iter__()

  • Return the iterator object itself.

iterator.__next__()

  • Return the next item from the object. If there are no further items, raise the StopIteration exception.


Iteration in container

  • One method needs to be defined for container objects to provide iteration support.
  • It could be implemented by above Iterator Protocol. (Writer’s opinion)

container.__iter__()

  • Return an iterator object. This object is required to support the Iterator Protocol described above.


Additional Questions

Relation between Iterable and Iterator

  • As wrote above, we call all objects to Iterable which is capable of returning its members one at a time and one of its implmentation methods is using Iterator.
  • Implement __iter()__ method to class which you want to make Iterable to return Iterator. That Iterator should be implemented with __iter()__ method which returns itself and __next()__ method which returns its next member following to above Iterator Protocol in Iterator Types.


Difference between __iter__() and __getitem__()


Summary and Conclusion

At first I was just curious about Iterable and Iterator but those are little bit difficult when I searched.

In short, Iterable is an object capable of returning its members one at a time such as list, str, dict, file object and objects of any classes you define with an __iter__() method or with a __getitem__() method that implements Sequence semantics. We can commonly call object which can return its members one at a time.

Now Iterator is an object representing a stream of data. It can be implemented with two methods(iterator.__iter__() and iterator.__next__()) according to Iterator Protocol. Iterator is also Iterable because it has __iter__() method. We can make Iterable object via using this Iterator.

List returns Iterator when use its __iter__() method or call built-in function iter(). This Iterator internally implements two methods(iterator.__iter__() and iterator.__next__()).

a = [1, 2, 3]

print(type(a))
print(type(a.__iter__()))
print(type(iter(a)))

print()

print(dir(a))
print(dir(a.__iter__()))
print(dir(iter(a)))
<class 'list'>
<class 'list_iterator'>
<class 'list_iterator'>

['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']
['__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__length_hint__', '__lt__', '__ne__', '__new__', '__next__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setstate__', '__sizeof__', '__str__', '__subclasshook__']
['__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__length_hint__', '__lt__', '__ne__', '__new__', '__next__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setstate__', '__sizeof__', '__str__', '__subclasshook__']


Reference