slice-alias (was Re: New statement proposal for Python)

Alex Martelli aleaxit at yahoo.com
Sat Jun 16 04:44:37 EDT 2001


"Andrew Henshaw" <ahenshaw at apower dot com> wrote in message
news:tiljnnden7bc80 at corp.supernews.com...
    ...
> For instance,  one can alias (e.g. "lastName") a slice [16:32] of an Occam
> array of bytes "byteArray" with:
>
>         lastName IS [byteArray FROM 16 FOR 16]:
>
> and then use lastName as a new array name.  Then the first byte can be
> referrenced with:
>
>         lastName[0] := 'a'
>
> This, of course, will change the 17th byte  in byteArray to 'a'.
    ...
> This would be nice on Python as well, particularly since naming a list
slice
> actually creates a copy (perhaps I've missed some capability here).

Takes some work, and is untested, but...:

import types,sys

class ListSlice:
    def __init__(self, alist, start, stop=None):
        self.alist=alist
        self.start=start
        self.stop=stop
    def __stopper(self):
        if self.stop is None: return len(self.alist)
        else: return self.stop
    def __normindex(self, index, aslice=0):
        if index<0:
            result = self.__stopper()+index
        else:
            try: result = self.start+index
            except OverflowError:
                if aslice==2: return self.__stopper()
                raise
        if self.start<=result<self.__stopper():
            return result
        else:
            if aslice==1: return self.start
            elif aslice==2: return self.__stopper()
            else: raise IndexError, result
    def __sliceit(self, index):
        if index.step is not None:
            raise TypeError, "sequence index must be integer"
        newstart = self.__normindex(index.start,1)
        newstop = self.__normindex(index.stop,2)
        return newstart, newstop
    def __len__(self):
        return max(0, self.__stopper()-self.start)
    def __getitem__(self, index):
        if type(index)==types.SliceType:
            newstart, newstop = self.__sliceit(index)
            return self.alist[newstart:newstop]
        else:
            return self.alist[self.__normindex(index)]
    def __setitem__(self, index, value):
        if type(index)==types.SliceType:
            newstart, newstop = self.__sliceit(index)
            self.alist[newstart:newstop] = value
        else:
            self.alist[self.__normindex(index)] = value

>> base = list("prolegomena")
>> slic=ListSlice(base,2,6)
>>> ''.join(slic)
'oleg'
>>> ''.join(base)
'prolegomena'
>>> slic[:3]
['o', 'l', 'e']
>>> slic[2:]
['e', 'g']
>>> slic[1:4]
['l', 'e', 'g']
>>> slic[1:3]
['l', 'e']
>>> slic[1:3]=list("plop")
>>> ''.join(base)
'proplopgomena'
>>> ''.join(slic)
'oplo'
>>>

As you see, it itsn't perfect -- the slice should no doubt
adjust its length in some more circumstances, the better
to mimic a built-in sequence, specifically when it's subject
to slice-assignment.  But I hope it can get you started.


Alex






More information about the Python-list mailing list