On Wed, 31 Aug 2005 14:16:28 GMT, Ron Adam <[EMAIL PROTECTED]> wrote: [...] > >The problem with negative index's are that positive index's are zero >based, but negative index's are 1 based. Which leads to a non >symmetrical situations. > >Note that you can insert an item before the first item using slices. But >not after the last item without using len(list) or some value larger >than len(list).
IMO the problem is that the index sign is doing two jobs, which for zero-based reverse indexing have to be separate: i.e., to show direction _and_ a _signed_ offset which needs to be realtive to the direction and base position. A list-like class, and an option to use a zero-based reverse index will illustrate: >>> class Zbrx(object): ... def __init__(self, value=0): ... self.value = value ... def __repr__(self): return 'Zbrx(%r)'%self.value ... def __sub__(self, other): return Zbrx(self.value - other) ... def __add__(self, other): return Zbrx(self.value + other) ... >>> class Zbrxlist(object): ... def normslc(self, slc): ... sss = [slc.start, slc.stop, slc.step] ... for i,s in enumerate(sss): ... if isinstance(s, Zbrx): sss[i] = len(self.value)-1-s.value ... return tuple(sss), slice(*sss) ... def __init__(self, value): ... self.value = value ... def __getitem__(self, i): ... if isinstance(i, int): ... return '[%r]: %r'%(i, self.value[i]) ... elif isinstance(i, Zbrx): ... return '[%r]: %r'%(i, self.value[len(self.value)-1-i.value]) ... elif isinstance(i, slice): ... sss, slc = self.normslc(i) ... return '[%r:%r:%r]: %r'%(sss+ (list.__getitem__(self.value, slc),)) ... def __setitem__(self, i, v): ... if isinstance(i, int): ... list.__setitem__(self, i, v) ... elif isinstance(i, slice): ... sss, slc = self.normslc(i) ... list.__setitem__(self.value, slc, v) ... def __repr__(self): return 'Zbrxlist(%r)'%self.value ... >>> zlast = Zbrx(0) >>> zbr10 = Zbrxlist(range(10)) >>> zbr10[zlast] '[Zbrx(0)]: 9' >>> zbr10[zlast:] '[9:None:None]: [9]' >>> zbr10[zlast:zlast] = ['end'] >>> zbr10 Zbrxlist([0, 1, 2, 3, 4, 5, 6, 7, 8, 'end', 9]) >>> ztop = Zbrx(-1) >>> zbr10[ztop:ztop] = ['final'] >>> zbr10 Zbrxlist([0, 1, 2, 3, 4, 5, 6, 7, 8, 'end', 9, 'final']) >>> zbr10[zlast:] "[11:None:None]: ['final']" >>> zbr10[zlast] "[Zbrx(0)]: 'final'" >>> zbr10[zlast+1] '[Zbrx(1)]: 9' >>> zbr10[zlast+2] "[Zbrx(2)]: 'end'" > > >>> a = list('abcde') > >>> a[len(a):len(a)] = ['end'] > >>> a >['a', 'b', 'c', 'd', 'e', 'end'] > > >>> a[-1:-1] = ['last'] > >>> a >['a', 'b', 'c', 'd', 'e', 'last', 'end'] # Second to last. > > >>> a[100:100] = ['final'] > >>> a >['a', 'b', 'c', 'd', 'e', 'last', 'end', 'final'] > >>> a = Zbrxlist(list('abcde')) >>> a Zbrxlist(['a', 'b', 'c', 'd', 'e']) Forgot to provide a __len__ method ;-) >>> a[len(a.value):len(a.value)] = ['end'] >>> a Zbrxlist(['a', 'b', 'c', 'd', 'e', 'end']) lastx refers to the last items by zero-based reverse indexing >>> a[lastx] "[Zbrx(0)]: 'end'" >>> a[lastx:lastx] = ['last'] >>> a Zbrxlist(['a', 'b', 'c', 'd', 'e', 'last', 'end']) As expected, or do you want to define different semantics? You still need to spell len(a) in the slice somehow to indicate beond the top. E.g., >>> a[lastx-1:lastx-1] = ['final'] >>> a Zbrxlist(['a', 'b', 'c', 'd', 'e', 'last', 'end', 'final']) Perhaps you can take the above toy and make something that works they way you had in mind? Nothing like implementation to give your ideas reality ;-) Regards, Bengt Richter -- http://mail.python.org/mailman/listinfo/python-list