Re: Newbi Q: What is a rational for strings not being lists in Python?
On 10/16/07, Matt McCredie [EMAIL PROTECTED] wrote: [quote] 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) [end-quote] I agree, my first example: def reverse1(xs): if xs == []: return xs else: return (reverse1 (xs[1:])) + [xs[0]] is very inefficient. I posted it just to illustrate my question about strings and lists in Python. The cost of reverse1() is proportional to: (N - 1) + (N -2) + ...+1 = N(N - 1) /2, which in turn is ~ square(N), where N is the number of elements in the list. For example, reverse2() demonstrates a better algorithm, with cost proportional to N: def head(xs) : if xs == []: return [] else: return xs[0] def tail(xs) : if xs == []: return [] else: return xs[1:] def addHead (acc, xs): if xs == []: return acc else: return addHead ([head(xs)] + acc, tail(xs)) def reverse2 (xs): if xs == []: return [] else: return addHead([], xs) [quote] 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. [end-quote] Casting and writing wrapper classes is not interesting. Life becomes much easier when String is a subtype of List, and when you have polymorphic functions making no difference between String and List. [quote] 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. [end-quote] As for me, I am perfectly happy with immutable types, I would rather do without mutable ones. And thanks, everybody, for reminding me that Python is a 'side effect' language, from which by definition follows that it should have mutable lists along with immutable strings. So answer to my question What is a rational for strings not being lists in Python? is quite trivial, as Simon B. ([EMAIL PROTECTED]) [EMAIL PROTECTED]wrote: Lists are mutable, strings are not, so so strings can't support all a list's methods. Sorry again for trivial question :(worked too much with Haskell recently and mostly forgot about mutable types , I guess ) ... [quote] 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 [end-quote] -- Dmitri O. Kondratiev [EMAIL PROTECTED] http://www.geocities.com/dkondr -- http://mail.python.org/mailman/listinfo/python-list
Re: Newbi Q: What is a rational for strings not being lists in Python?
On 10/16/07, Benjamin [EMAIL PROTECTED] wrote: Good explanation, but basically strings are immutable so they can be used in dicts. Nope. Value types should always be immutable. http://c2.com/cgi/wiki?ValueObjectsShouldBeImmutable -- Cheers, Simon B. [EMAIL PROTECTED] http://www.brunningonline.net/simon/blog/ GTalk: simon.brunning | MSN: small_values | Yahoo: smallvalues -- http://mail.python.org/mailman/listinfo/python-list
Re: Newbi Q: What is a rational for strings not being lists in Python?
On 2007-10-16, Simon Brunning [EMAIL PROTECTED] wrote: On 10/16/07, Benjamin [EMAIL PROTECTED] wrote: Good explanation, but basically strings are immutable so they can be used in dicts. Nope. Value types should always be immutable. http://c2.com/cgi/wiki?ValueObjectsShouldBeImmutable And strings are considered value objects because... -- Neil Cerutti -- http://mail.python.org/mailman/listinfo/python-list
Re: Newbi Q: What is a rational for strings not being lists in Python?
On Oct 15, 3:03 pm, Matt McCredie [EMAIL PROTECTED] wrote: So, the best way to get the posted code to work [...] is to cast the input parameter to a list first. snip 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' Pardon my nit-picking, but the line x = list(s) is not casting anything. It is constructing a new list from the iterable s. Even if s is a list, you get back a new list with the same elements: Python 2.5.1 (r251:54863, Apr 18 2007, 08:51:08) [MSC v.1310 32 bit (Intel)] on win32 lst = list(ABCDEF) id(lst) 12249928 id(list(lst)) 12250088 (This was a surprise to me too - I thought list(listVar) just returned back the original listVar.) -- Paul -- http://mail.python.org/mailman/listinfo/python-list
Newbi Q: What is a rational for strings not being lists in Python?
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 [EMAIL PROTECTED] http://www.geocities.com/dkondr On 10/15/07, Dmitri O.Kondratiev [EMAIL PROTECTED] 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 [EMAIL PROTECTED] http://www.geocities.com/dkondr On 10/15/07, Gary Herron [EMAIL PROTECTED] 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 -- http://mail.python.org/mailman/listinfo/python-list
Re: Newbi Q: What is a rational for strings not being lists in Python?
On 10/15/07, Dmitri O.Kondratiev [EMAIL PROTECTED] 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? Lists are mutable, strings are not, so so strings can't support all a list's methods. -- Cheers, Simon B. [EMAIL PROTECTED] http://www.brunningonline.net/simon/blog/ GTalk: simon.brunning | MSN: small_values | Yahoo: smallvalues -- http://mail.python.org/mailman/listinfo/python-list
Re: Newbi Q: What is a rational for strings not being lists in Python?
On 2007-10-15, Simon Brunning [EMAIL PROTECTED] wrote: On 10/15/07, Dmitri O.Kondratiev [EMAIL PROTECTED] 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? Lists are mutable, strings are not, so so strings can't support all a list's methods. -- http://mail.python.org/mailman/listinfo/python-list
Re: Newbi Q: What is a rational for strings not being lists in Python?
On 10/15/07, Dmitri O.Kondratiev [EMAIL PROTECTED] 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 [EMAIL PROTECTED] http://www.geocities.com/dkondr On 10/15/07, Dmitri O.Kondratiev [EMAIL PROTECTED] 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 [EMAIL PROTECTED] http://www.geocities.com/dkondr On 10/15/07, Gary Herron [EMAIL PROTECTED] 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 -- http://mail.python.org/mailman/listinfo/python-list
Re: Newbi Q: What is a rational for strings not being lists in Python?
On Oct 15, 3:03 pm, Matt McCredie [EMAIL PROTECTED] wrote: On 10/15/07, Dmitri O.Kondratiev [EMAIL PROTECTED] 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 [EMAIL PROTECTED] http://www.geocities.com/dkondr On 10/15/07, Dmitri O.Kondratiev [EMAIL PROTECTED] 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 [EMAIL PROTECTED] http://www.geocities.com/dkondr On 10/15/07, Gary Herron [EMAIL PROTECTED] 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 -- http://mail.python.org/mailman/listinfo/python-list