Handling slices

Alex Martelli aleax at aleax.it
Sat Apr 12 18:14:12 EDT 2003


Michael Hudson wrote:

> Francois Pinard <pinard at iro.umontreal.ca> writes:
> 
>> Hi, Python friends.
>> 
>> I'm currently using Python 2.2.1.  How does one support slices when given
>> to __getitem__?  Suppose I get a slice object.  How can I use it to get
>> a slice of a local array?  In other words, how one does apply a slice?
> 
> In 2.2.1, by hand, I think.

Essentially, yes, though it can be nicer than this...:

> def __getitem__(self, item):
>     if isinstance(item, types.SliceType):
>        if item.step != 1:
>           raise ValueError
>        if item.start is None:
>           start = 0
>        else:
>           start = item.start
>        if item.stop is None:
>           stop = len(self.local_array)
>        else:
>           stop = item.stop
>        return self.local_array[start:stop]

I'd probably take another tack, such as (warning, untested!!!)...:

def applyslice(asequence, aslice):
    seqlen = len(asequence)
    def mkidx(x, default):
        if x is None: return default
        elif x>=0: result = x
        else: result = x + seqlen
        return max(0, min(x, seqlen-1))
    if aslice.step is None: step = 1
    else: step = aslice.step
    if step > 0:
        default_start = 0
        default_stop = seqlen
    else:
        default_start = seqlen-1
        default_stop = -1
    start = mkidx(aslice.start, default_start)
    stop = mkidx(aslice.stop, default_stop)
    return type(asequence)([asequence[z]
            for x in xrange(start, stop, step)
           ])

of course, this needs to be refactored (and how!) to also
be usable for __setitem__ AND __delitem__... and it sure
makes a LOT of sense to specialcase the common case where
step is 1 to delegate right to asequence's slicing...


> I presume you don't need to be told that this is all much nicer in
> 2.3...

Given that built-in sequences now accept slice objects in their
__getitem__, all of the above becomes just a
    return asequence[aslice]
which IS indeed nicer;-).  But you might still need to keep the
applyslice function around in case you need to deal with sequence
types from older extensions, or the like...


Alex





More information about the Python-list mailing list