Bug in string.find; was: Re: Proposed PEP: New style indexing,was Re: Bug in slice type
Bengt Richter
bokr at oz.net
Fri Sep 2 22:53:52 EDT 2005
On Wed, 31 Aug 2005 14:16:28 GMT, Ron Adam <rrr at ronadam.com> 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
More information about the Python-list
mailing list