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

Matt McCredie mccredie at gmail.com
Mon Oct 15 16:03:36 EDT 2007


On 10/15/07, Dmitri O.Kondratiev <dokondr 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
> dokondr at gmail.com
> http://www.geocities.com/dkondr
>
>  On 10/15/07, Dmitri O.Kondratiev <dokondr 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
> > dokondr at gmail.com
> > http://www.geocities.com/dkondr
> >
> >
> >
> > On 10/15/07, Gary Herron < gherron 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.

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



More information about the Python-list mailing list