Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Iterators for built-in containers

From my understanding so far, you can easily create an iterator for a user-defined object by simply defining both the __iter__ method and the __next__ method for it. That's pretty intuitive to understand.

I also get it that you can manually build an iterator for any built-in container by simply calling the iter() method on that container.

Using basically any container as an example, what I don't understand is why they don't define a __next__ method for themselves. Instead, when calling the iter method on a container (ergo, <container>.__iter__) it returns a new object of type <container_type>_iterator and not the container itself.


So finally, the question is, why do container objects delegate their iterator functionality to separate <type>_iterator objects instead of defining it themselves?

like image 227
Dimitris Fasarakis Hilliard Avatar asked Jan 08 '23 08:01

Dimitris Fasarakis Hilliard


1 Answers

If the container was its own iterator (e.g. provided a __next__ method), you could only iterate over it in one place. You could not have independent iterators. Each call to __next__ would give the next value in the container and you'd not be able to go back to the first value; you have in effect a generator that could only ever yield the values in the container just the once.

By creating separate iterators for a given container, you can iterate independently:

>>> lst = ['foo', 'bar', 'baz']
>>> it1 = iter(lst)
>>> it2 = iter(lst)
>>> next(it1)
'foo'
>>> next(it2)
'foo'
>>> list(it1)
['bar', 'baz']
>>> next(it2)
'bar'
like image 184
Martijn Pieters Avatar answered Jan 15 '23 13:01

Martijn Pieters