Strange behaviour with reversed()
Gabriel Genellina
gagsl-py2 at yahoo.com.ar
Thu Oct 18 01:49:12 EDT 2007
En Thu, 18 Oct 2007 01:31:13 -0300, Steven D'Aprano
<steve at REMOVE-THIS-cybersource.com.au> escribió:
> I don't understand how reversed() is operating. I've read the description
> in the docs:
>
> reversed(seq)
> Return a reverse iterator. seq must be an object which supports the
> sequence protocol (the __len__() method and the __getitem__() method with
> integer arguments starting at 0). New in version 2.4.
>
> and help(reversed) but neither gives any insight to what happens when you
> use reversed() on a sequence, then modify the sequence.
A reversed object is rather simple: it stores the original sequence (a
reference, as usual, not a copy!) and the next index to use, starting at
len-1. Each time the next() method is called, the index is decremented
until it goes below 0.
This is more or less the equivalent Python code:
class Reversed:
def __init__(self, seq):
n = len(seq)
self.index = n-1
self.seq = seq
def __iter__(self):
return self
def next(self):
index = self.index
if index>=0:
try: item = self.seq[index]
except (IndexError,StopIteration): pass
else:
self.index -= 1
return item
self.index = -1
self.seq = None
raise StopIteration
Note that the starting index is determined at creation time, not when the
iteration begins. So, if you create a reversed object over a list
containing 3 elements, the first returned element will be seq[2], then
seq[1], then seq[0]. It doesn't matter if you modify the list after
creating the reversed object but before starting the iteration: it will
start at seq[2] even if it's not the last item, and will silently stop if
seq[2] is not a valid index anymore.
--
Gabriel Genellina
More information about the Python-list
mailing list