reseting an iterator

J. Cliff Dyer jcd at sdf.lonestar.org
Fri May 22 16:13:39 EDT 2009


On Fri, 2009-05-22 at 10:54 -0700, Jan wrote: 
> 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.
> 

You are correct:  It is an iterable, not an iterator.  However, that's
not a disagreement with me.  It may not be an iterator (and I probably
should have said so) but it works, and it solves the OP's problem.
> > 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
> 

Did you try running my code?  I did.  It works on my computer.  What
error message did you get?

Cheers,
Cliff





More information about the Python-list mailing list