Re: Newbi Q: Recursively reverse lists but NOT strings?
ot mode='private joke' story stargaming, I caught it first this time !-) intrusion pedant=TrueShouldn't that be s-o-r-r-y :-)/intrusion *ot -- http://mail.python.org/mailman/listinfo/python-list
Re: Newbi Q: Recursively reverse lists but NOT strings?
Paddy a écrit : ot mode='private joke' story stargaming, I caught it first this time !-) intrusion pedant=TrueShouldn't that be s-o-r-r-y :-)/intrusion crying Oui :( /crying *ot -- http://mail.python.org/mailman/listinfo/python-list
Re: Newbi Q: Recursively reverse lists but NOT strings?
OTanswering to Dmitri O.KondratievOT On Sunday 14 October 2007 5:06:19 pm 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? Because an empty string doesn't compare equal to an empty list. So if xs is not a list, the test always fails, and you always go to the 'else' branch. Now since in Python, most (and at least all builtins) empty containers and/or sequence types evals to false in a boolen context, there's an obvious fix to your function: def reverse(xs): if xs: return xs else: return (reverse (xs[1:])) + [xs[0]] Anyway, there's a much simpler solution: reverse = lambda x : x[::-1] which is so simple it doesn't even justify a function call !-) Oh, and, yes, while we're at it: Help on class reversed in module __builtin__: class reversed(object) | reversed(sequence) - reverse iterator over values of the sequence HTH -- http://mail.python.org/mailman/listinfo/python-list
Re: Newbi Q: Recursively reverse lists but NOT strings?
Bruno Desthuilliers a écrit : OTanswering to Dmitri O.KondratievOT (snip) def reverse(xs): if xs: return xs else: return (reverse (xs[1:])) + [xs[0]] I meant: def reverse(xs): if not xs: (etc...) of course... ot mode='private joke' story stargaming, I caught it first this time !-) *ot -- http://mail.python.org/mailman/listinfo/python-list
Re: Newbi Q: Recursively reverse lists but NOT strings?
Steven D'Aprano a écrit : (snip) def myreversed(sequence): if isinstance(sequence, basestring): return type(sequence)().join(reversed(sequence)) else: return type(sequence)(reversed(sequence)) (in fact, that's so simple I wonder why the built-in reversed() doesn't do that). Because it returns an iterator, not a sequence. Building back the appropriate sequence type from when needed it is usually a definitive no-brainer, and there are case where you definitively *don't* want a full sequence to be built (like when iterating backward over a millions-element long list...). Definitively the right design choice here IMHO. My 2 cents -- http://mail.python.org/mailman/listinfo/python-list
Re: Newbi Q: Recursively reverse lists but NOT strings?
On Sunday 14 October 2007 5:06:19 pm 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? Thanks, Dima I didn't try anything but it looks like your calling your function in your else block like this (e.g., reverse('bc')) everytime. your else block isn't really ending itself, just repeating itself. I could be wrong but from a quick glance you'll need to end it for sure when dealing with recursion. maybe also trying to reverse using the iterator function reversed() or this shortcut may help e.g, 'abc'[::-1] - 'cba'. good luck! -- Best Regards Victor B. Gonzalez -- http://mail.python.org/mailman/listinfo/python-list
Re: Newbi Q: Recursively reverse lists but NOT strings?
On Mon, 15 Oct 2007 02:11:27 -0400, Victor B. Gonzalez wrote: On Sunday 14 October 2007 5:06:19 pm 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? Becauese you test if `xs` is an empty list which is never true when you call the function with a string. So it never ends. '' != [] Ciao, Marc 'BlackJack' Rintsch -- http://mail.python.org/mailman/listinfo/python-list
Re: Newbi Q: Recursively reverse lists but NOT strings?
On Oct 15, 2:30 am, 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: ... 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 -- http://mail.python.org/mailman/listinfo/python-list
Re: Newbi Q: Recursively reverse lists but NOT strings?
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: Recursively reverse lists but NOT strings?
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: Recursively reverse lists but NOT strings?
Dmitri O.Kondratiev schrieb: 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: Not necessarily, you can handle both cases in one function: def reverse(xs): if xs in [[], '']: return xs return (reverse (xs[1:])) + [xs[0], [xs[0]]][isinstance(list, xs)] but this is evil(tm) and violates Rule #1, #2 of import this and several others. Ok. Now regarding in-place reversal of a list: why this ? : ls = [1,2,3].reverse() ls print [1,2,3].reverse() None I mean, why ls is empty after assignment? That's what in-place means, [].reverse() changes the list in-place and does not return the list to the caller. cheers Paul -- http://mail.python.org/mailman/listinfo/python-list
Re: Newbi Q: Recursively reverse lists but NOT strings?
On Mon, 15 Oct 2007 13:13:48 +0200, paul wrote: Dmitri O.Kondratiev schrieb: 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: Not necessarily, you can handle both cases in one function: def reverse(xs): if xs in [[], '']: return xs return (reverse (xs[1:])) + [xs[0], [xs[0]]][isinstance(list, xs)] but this is evil(tm) and violates Rule #1, #2 of import this and several others. I'm not sure if you consider the Zen of Python to be numbered from 1 or 0, so here are the first three: Beautiful is better than ugly. Explicit is better than implicit. Simple is better than complex. I'm not sure why you say that function violates two of those three. Well, okay, it's a bit ugly. I would say it violates this rule: There should be one-- and preferably only one --obvious way to do it. Have I missed something? Nobody seems to have pointed out the existence of reversed(), which works on both lists and strings. ''.join(reversed(abc)) 'cba' list(reversed(range(3))) [2, 1, 0] It doesn't take much to make a more user-friendly version: def myreversed(sequence): if isinstance(sequence, basestring): return type(sequence)().join(reversed(sequence)) else: return type(sequence)(reversed(sequence)) (in fact, that's so simple I wonder why the built-in reversed() doesn't do that). -- Steven -- http://mail.python.org/mailman/listinfo/python-list
Re: Newbi Q: Recursively reverse lists but NOT strings?
On 10/15/07, Steven D'Aprano [EMAIL PROTECTED] wrote: ''.join(reversed(abc)) 'cba' list(reversed(range(3))) [2, 1, 0] It doesn't take much to make a more user-friendly version: def myreversed(sequence): if isinstance(sequence, basestring): return type(sequence)().join(reversed(sequence)) else: return type(sequence)(reversed(sequence)) (in fact, that's so simple I wonder why the built-in reversed() doesn't do that). simple: In the face of ambiguity, refuse the temptation to guess. :-) -- http://mail.python.org/mailman/listinfo/python-list
Re: Newbi Q: Recursively reverse lists but NOT strings?
On Mon, 15 Oct 2007 14:47:30 +0200, Francesco Guerrieri wrote: def myreversed(sequence): if isinstance(sequence, basestring): return type(sequence)().join(reversed(sequence)) else: return type(sequence)(reversed(sequence)) (in fact, that's so simple I wonder why the built-in reversed() doesn't do that). simple: In the face of ambiguity, refuse the temptation to guess. What ambiguity? What guess? The above is completely unambiguous: it returns a sequence of the same type as the input. It doesn't support xrange objects, but that's not really a great loss. -- Steven. -- http://mail.python.org/mailman/listinfo/python-list
Re: Newbi Q: Recursively reverse lists but NOT strings?
Dmitri O.Kondratiev 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: True, they are not both lists, but they *are* both sequences, with some things in common. In particular xs[::-1] will reverse both types of objects. And even if you roll you own reversal function, you don't need two. One will do. Gary Herron 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] mailto:[EMAIL PROTECTED] http://www.geocities.com/dkondr On 10/15/07, *Gary Herron* [EMAIL PROTECTED] mailto:[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: Recursively reverse lists but NOT strings?
On 10/15/07, Steven D'Aprano [EMAIL PROTECTED] wrote: On Mon, 15 Oct 2007 14:47:30 +0200, Francesco Guerrieri wrote: def myreversed(sequence): if isinstance(sequence, basestring): return type(sequence)().join(reversed(sequence)) else: return type(sequence)(reversed(sequence)) (in fact, that's so simple I wonder why the built-in reversed() doesn't do that). simple: In the face of ambiguity, refuse the temptation to guess. What ambiguity? What guess? The above is completely unambiguous: it returns a sequence of the same type as the input. It doesn't support xrange objects, but that's not really a great loss. I could say that it depends on the xrange object.. but the truth is that I answered too quickly. Your suggestion was not ambiguous. Sorry :-) francesco -- http://mail.python.org/mailman/listinfo/python-list
Re: Newbi Q: Recursively reverse lists but NOT strings?
On 10/15/07, Steven D'Aprano [EMAIL PROTECTED] wrote: On Mon, 15 Oct 2007 13:13:48 +0200, paul wrote: Dmitri O.Kondratiev schrieb: 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: Not necessarily, you can handle both cases in one function: def reverse(xs): if xs in [[], '']: return xs return (reverse (xs[1:])) + [xs[0], [xs[0]]][isinstance(list, xs)] but this is evil(tm) and violates Rule #1, #2 of import this and several others. I'm not sure if you consider the Zen of Python to be numbered from 1 or 0, so here are the first three: Beautiful is better than ugly. Explicit is better than implicit. Simple is better than complex. I'm not sure why you say that function violates two of those three. Well, okay, it's a bit ugly. I would say it violates this rule: There should be one-- and preferably only one --obvious way to do it. Have I missed something? Nobody seems to have pointed out the existence of reversed(), which works on both lists and strings. ''.join(reversed(abc)) 'cba' list(reversed(range(3))) [2, 1, 0] It doesn't take much to make a more user-friendly version: def myreversed(sequence): if isinstance(sequence, basestring): return type(sequence)().join(reversed(sequence)) else: return type(sequence)(reversed(sequence)) (in fact, that's so simple I wonder why the built-in reversed() doesn't do that). Probably because reversed()'s primary use case is iteration, and it doesn't make sense to do the magic to return full objects there. The use case where you need to reverse a string or a list, with no context about what it will be, and where you're not iterating over the result (so a simple reversed() isn't practical) seems to be pretty obscure to me, so that there's not an obvious answer isn't surprising. There is the slightly non-obvious answer of sequence[::-1], though, which I think is perfectly satisfactory. -- http://mail.python.org/mailman/listinfo/python-list
Re: Newbi Q: Recursively reverse lists but NOT strings?
On 10/15/07, Gary Herron [EMAIL PROTECTED] wrote: Dmitri O.Kondratiev 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: True, they are not both lists, but they *are* both sequences, with some things in common. In particular xs[::-1] will reverse both types of objects. And even if you roll you own reversal function, you don't need two. One will do. Gary Herron 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? mylist[::-1] is interpreted as mylist[slice(None,None,-1)], and the slice object has a method, 'indices' that computes the right endpoints for what you want to do. So: myseq = (1,2,3) myseq[::-1] (3, 2, 1) myseq[slice(None,None,-1)] (3, 2, 1) myseq[None:None:-1] (3, 2, 1) etc. Thanks, Dmitri O. Kondratiev [EMAIL PROTECTED] mailto:[EMAIL PROTECTED] http://www.geocities.com/dkondr On 10/15/07, *Gary Herron* [EMAIL PROTECTED] mailto:[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 -- http://mail.python.org/mailman/listinfo/python-list