Strange behaviour with reversed()

Andreas Kraemer akraemer at sbcglobal.net
Thu Oct 18 14:45:34 EDT 2007


On Oct 18, 2:25 am, Duncan Booth <duncan.bo... at invalid.invalid> wrote:
> Steven D'Aprano <st... at REMOVE-THIS-cybersource.com.au> wrote:
> >> 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.
>
> > You know, that's probably the *least* intuitive behaviour possible.
>
> > For reversed() to iterate over the input as it was at creation time is
> a
> > reasonable design choice; for it to iterate over the input as it is at
> > call time is also a reasonable design choice; but for it to iterate
> over
> > some unholy mutant melding of the sequence as-it-was and as-it-is is
> > simply bizarre. I hope it just fell out of the implementation and
> wasn't
> > a deliberate design choice.
>
> You mean that you don't find it intuitive that it iterates through the
> indices that existed at creation time and returns the values as they are
> now? I'd have said that was the *most* intuitive behaviour.
>
> The only other behaviours I would regard as intuitive for iteration over
> a mutating sequence would be to throw an exception either for mutating
> the sequence while the iterator exists or for using the iterator after a
> mutation.

Maybe it would have been slightly more intuitive if reversed() had
been implemented like this,

def Reversed(seq):
  for i in xrange(len(seq)-1,-1,-1):
    yield seq[i]

so that the length of the sequence is determined when the iteration
starts, not when the iterator is created?

The unfortunate naming may also have added to the confusion since its
similarity to "sorted" suggests that a copy of the list is returned.
However,

>>> type(reversed([]))
<type 'listreverseiterator'>

and for comparison

>>> type(iter([]))
<type 'listiterator'>

reveals what it really is.

-Andreas




More information about the Python-list mailing list