On Oct 11, 1:40 am, Antoon Pardon <antoon.par...@rece.vub.ac.be> wrote: > On Sat, Oct 09, 2010 at 01:37:03AM +0000, Steven D'Aprano wrote: > > On Fri, 08 Oct 2010 15:53:17 -0400, Jed Smith wrote: > > > > On Fri, Oct 8, 2010 at 1:26 PM, Steven D'Aprano > > > <st...@remove-this-cybersource.com.au> wrote: > > >> On Fri, 08 Oct 2010 10:21:16 +0200, Antoon Pardon wrote: > > > >>> Personnaly I find it horrible > > >>> that in the following expression: L[a:b:-1], it is impossible to give > > >>> a numeric value to b, that will include L[0] into the reversed slice. > > > >>>>> L = [1, 2, 3, 4, 5] > > >>>>> L[5:-6:-1] > > >> [5, 4, 3, 2, 1] > > > >>>> a = [1, 2, 3, 4, 5, 6] > > >>>> a[::-1] > > > [6, 5, 4, 3, 2, 1] > > > Well of course that works, that is the standard Python idiom for > > reversing a sequence. > > > But the point was that Antoon claimed that there is no numeric value for > > the end position that will include L[0] in the reversed slice. My example > > shows that this is not correct. > > I stand by that claim. I think it was fairly obvious that what I meant > was that it was impossible to give such a numeric value that would work > with arbitrary L. > > if L2 == list(reversed(L1)) and a and b are in the range 1 < x <= len(L), > we have the following invariant. > > L1[a:b] == L2[b-1:a-1:-1] > > However this no longer works if either nr is 0. That means that if a and > be are computed values, that may return 0 to indicate which slice you > want; that if you want the reversed slice, there is no straightforward > way to get that reversed slice with extended slice notation. >
Here is a transformation that uses extended slice notation under the hood, while preserving your semantics for 0 <= l <= h def reverse_list_slice(lst, l, h): if l == 0 and h == 0: return [] h = h - 1 if h else None l = l - 1 if l else None return lst[h:l:-1] It's not exactly elegant, but it's not a ton of code either. Here is how I tested it: lst = [0, 1, 2, 3, 4] for a in range(len(lst)): for width in range(len(lst)-a): b = a + width print a, b rev1 = list(reversed(lst[a:b])) rev2 = reverse_list_slice(lst, a, b) if rev1 != rev2: print a, b print rev1 print rev2 raise 'invariant broken' If you want to look at some of the internals for cpython, you can find them here: http://svn.python.org/view/python/trunk/Objects/sliceobject.c?view=markup http://svn.python.org/view/python/trunk/Objects/listobject.c?view=markup The basic iteration that happens is as follows: for (cur = start, i = 0; i < slicelength; cur += step, i++) { it = src[cur]; Py_INCREF(it); dest[i] = it; } -- http://mail.python.org/mailman/listinfo/python-list