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?
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'
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With