Reuseable iterators - which is better?

Mitja Trampus nun at example.com
Fri Jun 23 15:11:43 EDT 2006


zefciu wrote:
> In the tutorial there is an example iterator class that revesrses the
> string given to the constructor.  The problem is that this class works
> only once, unlike built-in types like string.  How to modify it that it
> could work several times?  I have tried two approaches.  They both work,
> but which of them is stylistically better?

Of the two posted below, I would much prefer the second one because iterators are not 
meant to be reused (so they can be used on streams and similar as well). Therefore, 
"resetting" an iterator by creating a new, similar one, is the natural way. Beware, 
however, that your code does not actually create a new iterator and breaks if you want to 
concurrently use more than one iterator of the same Reverse instance.
The "normal" way would be to have
   def __iter__(self): return Reverse(self)
as a method of the sequence that is meant to be iterated over in reverse. Plus, of course, 
everything but the __iter__ method from your second "reusable" iterator (which now isn't 
reusable any more).

> class Reverse: #original one
>     "Iterator for looping over a sequence backwards"
>     def __init__(self, data):
>         self.data = data
>         self.index = len(data)
>     def __iter__(self):
>         return self
>     def next(self):
>         if self.index == 0:
>             raise StopIteration
>         self.index = self.index - 1
>         return self.data[self.index]
> 
> class Reverse: #1st approach
>     "Reuseable Iterator for looping over a sequence backwards"
>     def __init__(self, data):
>         self.data = data
>         self.index = len(data)
>     def __iter__(self):
>         return self
>     def next(self):
>         if self.index == 0:
>             	self.index = len(self.data) #Reset when previous 								#
> iterator goes out
> 		raise StopIteration
>         self.index = self.index - 1
>         return self.data[self.index]
> 
> class Reverse: #2nd approach
>     "Reuseable Iterator for looping over a sequence backwards"
>     def __init__(self, data):
>         self.data = data
>     def __iter__(self):
> 	self.index = len(self.data) #Reset as a part of iterator 							# creation
>         return self
>     def next(self):
>         if self.index == 0:
>             raise StopIteration
>         self.index = self.index - 1
>         return self.data[self.index]



More information about the Python-list mailing list