Bug in slice type

Michael Hudson mwh at python.net
Fri Aug 12 10:51:03 EDT 2005


Bryan Olson <fakeaddress at nowhere.org> writes:

> The Python slice type has one method 'indices', and reportedly:
>
>      This method takes a single integer argument /length/ and
>      computes information about the extended slice that the slice
>      object would describe if applied to a sequence of length
>      items. It returns a tuple of three integers; respectively
>      these are the /start/ and /stop/ indices and the /step/ or
>      stride length of the slice. Missing or out-of-bounds indices
>      are handled in a manner consistent with regular slices.
>
>      http://docs.python.org/ref/types.html
>
>
> It behaves incorrectly 

In some sense; it certainly does what I intended it to do.

> when step is negative and the slice includes the 0 index.
>
>
>      class BuggerAll:
>
>          def __init__(self, somelist):
>              self.sequence = somelist[:]
>
>          def __getitem__(self, key):
>              if isinstance(key, slice):
>                  start, stop, step = key.indices(len(self.sequence))
>                  # print 'Slice says start, stop, step are:', start,
>                    stop, step
>                  return self.sequence[start : stop : step]

But if that's what you want to do with the slice object, just write

                 start, stop, step = key.start, key.stop, key.step
                 return self.sequence[start : stop : step]

or even

                 return self.sequence[key]

What the values returned from indices are for is to pass to the
range() function, more or less.  They're not intended to be
interpreted in the way things passed to __getitem__ are.

(Well, _actually_ the main motivation for writing .indices() was to
use it in unittests...)

>      print           range(10) [None : None : -2]
>      print BuggerAll(range(10))[None : None : -2]
>
>
> The above prints:
>
>      [9, 7, 5, 3, 1]
>      []
>
> Un-commenting the print statement in __getitem__ shows:
>
>      Slice says start, stop, step are: 9 -1 -2
>
> The slice object seems to think that -1 is a valid exclusive
> bound, 

It is, when you're doing arithmetic, which is what the client code to
PySlice_GetIndicesEx() which in turn is what indices() is a thin
wrapper of, does

> but when using it to actually slice, Python interprets negative
> numbers as an offset from the high end of the sequence.
>
> Good start-stop-step values are (9, None, -2), or (9, -11, -2),
> or (-1, -11, -2). The later two have the advantage of being
> consistend with the documented behavior of returning three
> integers.

I'm not going to change the behaviour.  The docs probably aren't
especially clear, though.

Cheers,
mwh

-- 
  (ps: don't feed the lawyers: they just lose their fear of humans)
                                         -- Peter Wood, comp.lang.lisp



More information about the Python-list mailing list