Newbi Q: Recursively reverse lists but NOT strings?

George Sakkis george.sakkis at gmail.com
Mon Oct 15 02:43:11 EDT 2007


On Oct 15, 2:30 am, Gary Herron <gher... at islandtraining.com> wrote:
> Dmitri O.Kondratiev wrote:
>
> > The function I wrote (below) reverses lists all right:
>
> > def reverse(xs):
> >     if xs == []:
> >         return []
> >     else:
> >         return (reverse (xs[1:])) + [xs[0]]
>
> > >>> reverse ([1,2,3])
> > [3, 2, 1]
>
> > Yet when I try to reverse a string I  get:
>
> > >>> reverse ("abc")
>
> > ...
> > ...
> > ...
>
> >   File "C:\wks\python-wks\reverse.py", line 5, in reverse
>
> >     return (reverse (xs[1:])) + [xs[0]]
>
> >   File "C:\wks\python-wks\reverse.py", line 5, in reverse
>
> >     return (reverse (xs[1:])) + [xs[0]]
>
> >   File "C:\wks\python-wks\reverse.py", line 2, in reverse
>
> >     if xs == []:
>
> > RuntimeError: maximum recursion depth exceeded in cmp
>
> > What's wrong? Why recursion never stops?
>
> If you are doing this as an python-learning exercise, then read on.   If
> you are doing this reversal for real code, then try:
>
>   xs.reverse() for in-place reversal of a list (but not a string), or
>   result = xs[::-1] for creating a reversed copy of either a string or a
> list
>
> Your recursion stops when xs == [], but when you're stripping characters
> off a string,  like 'abc', the remaining portion will be 'bc', then 'c',
> than '', but never [] so you 'll never stop.
>
> Try:
>
> if xs == []:
>     return []
> elif xs == '':
>     return ''
> else:
>     ...

The 'else' clause also breaks for strings: the second operand is a
list, which cannot be concatenated to strings. Here's a version that
works for any type with the common slicing semantics:

def reverse(xs):
     if not xs:
        return xs
     else:
        return reverse(xs[1:]) + xs[:1]

print reverse([1,2,3])
print reverse((1,2,3))
print reverse('123')


George




More information about the Python-list mailing list