Immutable list reverse function

Terry Reedy tjreedy at home.com
Thu Jul 19 12:28:51 EDT 2001


"Martin Sjögren" <martin at strakt.com> wrote in message
news:mailman.995543208.24170.python-list at python.org...
>Is there a "good" way to write a fast reverse function for immutable
lists?

Lists are mutable.  That is why you can reverse them in place.  Three
possible questions:

Q1. How reverse an immutable sequence?

def tup_reverse(tup):
  ans = []
  for i in range(len(tup)-1, -1, -1):
    ans.append(tup(i))
  return tuple(ans)

or

def tup_reverse(tup):
  ans = list(tup)
  ans.reverse()
  return tuple(ans)

and similarly for str_reverse.  In 2.2a I believe we could write a more
generic

def seq_reverse(seq):
  t = type(seq)
  ...
  return t(ans)

Lutz *Programming Python* p492 gives (with slight renaming) this generic
version which will even work for sequence-like classes:

def reverse(seq):
  ans = seq[:0]   # empty seq of same type
  for i in range(len(seq)):
    ans = seq[i:i+1] + ans
  return ans

Q2. How reverse a list and get return value to chain in call sequence?

def reverse(lisp): # 'list' is builtin function; bad habit to use as name
  lisp.reverse()
  return lisp

Note 1: GvR decided to have list methods that modify in place NOT return
the list because he did not want people to introduce bugs in programs by
forgeting that list IS modified in place.

Note 2: One can reverse this decision by deriving a class from UserList.
In the just released Python 2.2a1, one derive the value-returning list
class directly from type list.


Q3. How get a reversed copy copy of list without modifying original?

You already answered this with:

def reverse(list):
    l = len(list)
    return [ list[l-i-1] for i in range(l) ]

>It works, but it's obviously not backwards compatible. Any suggestions?

See Q1 answer.

But Q3 seem not to really be your question.

>What I want to do is basically this: foo(reverse(create_a_list()))

If reverse returns a copy rather than the original, then the original list
is uselessly tossed away.  So see the Q2 answer.

>Instead of having to:

>>> list = create_a_list()
>>> list.reverse()
>>> foo(list)

Since this does not create two lists, it is more effecient than your
original alternative.

Terry J. Reedy






More information about the Python-list mailing list