Strange behaviour with reversed()

Andreas Kraemer akraemer at sbcglobal.net
Thu Oct 18 01:52:30 EDT 2007


On Oct 17, 9:31 pm, Steven D'Aprano <st... at REMOVE-THIS-
cybersource.com.au> wrote:
> 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.
>
> This works as I expected:
>
> >>> L = list("abc")
> >>> RL = reversed(L)
> >>> del L
> >>> list(RL)
>
> ['c', 'b', 'a']
>
> This suggests that reversed() makes a copy of the list:
>
> >>> L = list("abc")
> >>> RL = reversed(L)
> >>> L.append("d")
> >>> list(RL)
>
> ['c', 'b', 'a']
>
> This suggests that reversed() uses a reference to the original list:
>
> >>> RL = reversed(L)
> >>> L[0] = 'e'
> >>> list(RL)
>
> ['d', 'c', 'b', 'e']
>
> And these examples suggests that reversed() is confused, or at least
> confusing:
>
> >>> RL = reversed(L)
> >>> del L[2]
> >>> list(RL)
>
> []
>
> >>> L = list("abc")
> >>> RL = reversed(L)
> >>> L.insert(0, "d")
> >>> L
>
> ['d', 'a', 'b', 'c']>>> list(RL)
>
> ['b', 'a', 'd']
>
> Does anyone know what reversed() is actually doing?
>
> --
> Steven.

Without knowing the internals, it seems reversed() does exactly the
same as the following class:


class Reversed(object):
  def __init__(self,seq):
    self.seq = seq
    self.i = len(seq)
  def __iter__(self):
    return self
  def next(self):
    self.i -= 1
    if self.i < 0:
      raise StopIteration
    else:
      return self.seq[self.i]

so it doesn't copy anything, just book-keeping of indexes. I guess one
would call this kind of object a (special) "view" of the sequence.

Cheers,

Andreas




More information about the Python-list mailing list