Dimitris Fasarakis Hilliard
Dimitris Fasarakis Hilliard

Reputation: 160687

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?

Upvotes: 4

Views: 172

Answers (1)

Martijn Pieters
Martijn Pieters

Reputation: 1125368

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'

Upvotes: 9

Related Questions