Slice lists and extended slicing

Robert Kern robert.kern at gmail.com
Wed Jan 26 13:06:24 EST 2011


On 1/26/11 11:20 AM, Gerald Britton wrote:
> I'm looking at extended slicing and wondering when and how to use slice lists:
>
> slicing          ::=  simple_slicing | extended_slicing
> simple_slicing   ::=  primary "[" short_slice "]"
> extended_slicing ::=  primary "[" slice_list "]"
> slice_list       ::=  slice_item ("," slice_item)* [","]
> slice_item       ::=  expression | proper_slice | ellipsis
> proper_slice     ::=  short_slice | long_slice
> short_slice      ::=  [lower_bound] ":" [upper_bound]
> long_slice       ::=  short_slice ":" [stride]
> lower_bound      ::=  expression
> upper_bound      ::=  expression
> stride           ::=  expression
> ellipsis
>
> The semantics for an extended slicing are as follows. The primary must
> evaluate to a mapping object, and it is indexed with a key that is
> constructed from the slice list, as follows. If the slice list
> contains at least one comma, the key is a tuple containing the
> conversion of the slice items; otherwise, the conversion of the lone
> slice item is the key. The conversion of a slice item that is an
> expression is that expression. The conversion of an ellipsis slice
> item is the built-in Ellipsis object. The conversion of a proper slice
> is a slice object (see section The standard type hierarchy) whose
> start, stop and step attributes are the values of the expressions
> given as lower bound, upper bound and stride, respectively,
> substituting None for missing expressions.
>
> I'd thought that I could do this:
>
>>>> l = [1,2,3,4,5]
>>>> l[0:1, 3:4]
> Traceback (most recent call last):
>    File "<stdin>", line 1, in<module>
> TypeError: list indices must be integers, not tuple
>
> but that clearly doesn't work!  So, when and how can one use slice lists?

The object just needs to implement its __getitem__(self, key) method 
appropriately. list objects have an implementation that only processes integer 
indices and slices.

The original semantics that motivated this syntax feature is not to take several 
slices from a sequence and concatenate them together. Rather, it was to support 
multidimensional slices for numpy arrays (or rather, numpy's predecessor Numeric).

[~]
|1> from numpy import arange

[~]
|2> A = arange(20).reshape([4,5])

[~]
|3> A
array([[ 0,  1,  2,  3,  4],
        [ 5,  6,  7,  8,  9],
        [10, 11, 12, 13, 14],
        [15, 16, 17, 18, 19]])

[~]
|4> A[1:3, 2:4]
array([[ 7,  8],
        [12, 13]])


list objects could be written to interpret a tuple of slices any way it wants 
to, including the semantics you seem to have expected. I would suggest, though, 
that the need for those semantics isn't common enough to warrant the syntactic 
sugar.

-- 
Robert Kern

"I have come to believe that the whole world is an enigma, a harmless enigma
  that is made terrible by our own mad attempt to interpret it as though it had
  an underlying truth."
   -- Umberto Eco




More information about the Python-list mailing list