# Newbi Q: What is a rational for strings not being lists in Python?

Benjamin musiccomposition at gmail.com
Tue Oct 16 04:39:20 CEST 2007

```On Oct 15, 3:03 pm, "Matt McCredie" <mccre... at gmail.com> wrote:
> On 10/15/07, Dmitri O.Kondratiev <doko... at gmail.com> wrote:
>
>
>
> > To clarify my point:
> > reverse()  is  a lucky one  - Python has variants of *this particular*
> > function both for lists and strings. Yet what about other list functions?
> > How in general, can I write a function that works  both on list and string
> > types? Both are sequences, right? Why string is not a subtype of a list
> > then?
> > The advantage of string being a list of elements, where element is a char is
> > that all list functions will work *without any modifications* on strings as
> > well as on other types of lists.
> > So, I am trying to understand: what is a rational for strings not being
> > lists in Python?
>
> > Thanks,
> > --
> > Dmitri O. Kondratiev
> > doko... at gmail.com
> >http://www.geocities.com/dkondr
>
> >  On 10/15/07, Dmitri O.Kondratiev <doko... at gmail.com> wrote:
> > > Gary, thanks for lots of info!
> > > Python strings are not lists! I got it now. That's a pity, I need two
> > different functions: one to reverse a list and one to reverse a string:
>
> > > def reverseList(xs):
> > >     if xs == []:
> > >         return xs
> > >     else:
> > >         return (reverseList (xs[1:])) + [xs[0]]
>
> > > def reverseStr(str):
> > >     if str == "":
> > >         return str
> > >     else:
> > >         return (reverseStr (str[1:])) + str[0]
>
> > > Ok. Now regarding in-place reversal of a list:
>
> > > >>> l = [1,2,3]
> > > >>> l
> > > [1, 2, 3]
> > > >>> l.reverse()
> > > >>> l
> > > [3, 2, 1]
>
> > > That was, as I expected. Good.
>
> > > Then why this ? :
>
> > > >>> ls = [1,2,3].reverse()
> > > >>> ls
>
> > > >>> print [1,2,3].reverse()
> > > None
>
> > > I mean, why ls is empty after assignment?
>
> > > Also, I couldn't find in the Python docs what this form of slicing means:
> > > xs[::-1]  ?
>
> > > It works for creating a reversed copy of either a string or a list, but
> > what does '::-1' syntax means?
>
> > > Thanks,
>
> > > Dmitri O. Kondratiev
> > > doko... at gmail.com
> > >http://www.geocities.com/dkondr
>
> > > On 10/15/07, 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:
> > > >     ...
>
> > > > Gary Herron
>
> > > > > Thanks,
> > > > > Dima
>
> The example you posted won't work with tuples either because they,
> like strings, are also immutable. So, the best way to get the posted
> code to work (which is a bad way to go about reversing a string, but I
> digress) is to cast the input parameter to a list first. The returned
> value will always be a list, but you will simply have to convert it
> back to the appropriate type when you are done.
>
> What is the purpose if immutability? It allows a value to be hashed. I
> don't want to get into a discussion about methods for hashing mutable
> types, if you are interested just do a search on the list archives.
> Hashing allows for quick comparisons of values, but more importantly
> it allows for values to be used as keys for the dict type. This is
> very important because, as you will soon find out if you keep learning
> the language, all namespaces in python are implemented as dicts.
Good explanation, but basically strings are immutable so they can be
used in dicts.
>
> So... if you want a mutable string, just cast it to a list, do your
> operations and cast it back to a string.
>
> Incidentally, the proper method for converting a list of characters to
> a string is by using the join method on an empty string.
>
> >>> s = "I am a string"
> >>> x = list(s)
> >>> x
>
> ['I', ' ', 'a', 'm', ' ', 'a', ' ', 's', 't', 'r', 'i', 'n', 'g']>>> "".join(x)
>
> 'I am a string'
>
> Matt

```