Reuseable iterators - which is better?

Z

zefciu

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?

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]
 
D

Diez B. Roggisch

zefciu said:
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?

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]



None. You don't reuse iterators! In the actualy example, reusage is
possible due to the whole data being known & available. But there might
be cases where this isn't possible - e.g. fetching data from a remote
location which is too large to fit into memory for re-iteration.

So generally speakiing, if you need an iterator, construct it.

Regards,

Diez
 
M

Mitja Trampus

zefciu said:
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]
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,777
Messages
2,569,604
Members
45,234
Latest member
SkyeWeems

Latest Threads

Top