reseting an iterator

Jan jan.plaza at plattsburgh.edu
Fri May 22 19:54:59 CEST 2009


On May 22, 9:46 am, "J. Cliff Dyer" <j... at sdf.lonestar.org> wrote:

> You don't need a reset method.  There is no hard and fast rule that
> __iter__ must return the object itself.  It just needs to return an
> iterator.  

I disagree.
If ITRATOR is a true iterator, ITRATOR.__iter__() must return
ITERATOR.
If ITERABLE is an iterable (but not necessarily an iterator)
ITRABLE.__iter__() must return an iterator.

> For example:
>
> >>> l = [1,2,3]
> >>> l.__iter__()
>
> <listiterator object at 0x7fd0da315850>>>> l is l.__iter__()
>
> False

[1,2,3] is an iterable but not an iterator, so this False result is
expected.
Compare this with the following.

>>> ii = iter([1,2,3])  # ii is an iterator.
>>> next(ii)
1
>>> jj = ii.__iter__() # call __iter__ method on an iterator
>>> ii is jj
True
>>> next(jj)
2

> Just create a class with an __iter__ method that returns a reset
> iterator object.
>
> class X(object):
>     def __init__(self, max=3):
>         self.counter = 0
>         self.max = max
>     def __iter__(self):
>         return self
>     def next(self):
>         if self.counter < self.max:
>             self.counter += 1
>             return self.counter
>         else:
>             raise StopIteration
>
> class Y(object):
>     def __iter__(self):
>         return X()
>
> In this setup, X has the problem you are trying to avoid, but Y behaves
> as a resettable iterable.

> y = Y()

This does not work.

With this, y is not an interator, and not even an iterable.

> for c in y:

This produces an error because by definition of for-loops
it is executed the same way as:

temp_iterator = iter(y) # temp_iterator is y
while True:
    try:
        print(next(temp_iterator)) # temp_iterator does not support
__next__()
    except StopIteration:
        break

Jan



More information about the Python-list mailing list