[Tutor] 'slice', etc

Steven D'Aprano steve at pearwood.info
Sat Dec 7 11:42:05 CET 2013


On Fri, Dec 06, 2013 at 04:39:28PM +0100, spir wrote:
> Hello,
> 
> How does slicing in Python really work? Apparently, there are slice objects 
> (start, past-end, step), generated using either the 'slice' builtin func or 
> the extended slicing syntax [i:k:s]. Is this correct? [1]

Correct. When you call something like this:

    obj[a]

Python calls the special dunder method __getindex__ with a as argument. 
If you use a colon inside the square brackets, such as these examples:

    obj[a:]
    obj[:b]
    obj[a:b]
    obj[a:b:c]

etc., Python constructs a slice object slice(a, b, c) and passes it to 
__getindex__ as before. So to implement slicing of your class, you 
should write something like this:

class Spam:
    def __getitem__(self, idx):
        if isinstance(idx, slice):
            # self[a:b:c]
            ...
        else:
            # self[a]
            ...


The slice object is just a way to get [a:b:c] notation as argument, it 
is *not* a view into the target object.

What your __getitem__ does is entirely up to you. Lists and strings and 
tuples return a new list, string or tuple. Numpy arrays return views. 
Your own classes could do anything.


> Does (only) the extended syntax (always) trigger slicing instead of 
> contructing a new subsequence? (new substring or sublist or whatever, 
> actually holding a section of the original sequence)

There is no "instead of". As soon as you use a colon inside square 
brackets [:] you get a slice passed to your object. Whether your object 
responds to that argument by returning a subsequence or a view, or 
something completely different, is entirely up to the object, not the 
slice.


> Are slices and subsequences transparently usable one for the other?

Of course not. They are completely different things. A slice has to be 
applied to a sequence before you get a subsequence:


py> s = slice(1, 12, 2)
py> "Hello World!"[s]
'el ol!'
py> list(range(100))[s]
[1, 3, 5, 7, 9, 11]


> PS: I searched but could not find a PEP specifically dedicated to 'slice' 
> only. Pointers welcome, especially to docs explaining purpose, rationale, 
> design, etc... Maybe this means slices have always existed and I just 
> missed them totally?

Slices go back to the earliest days of Python, although slice objects 
may be newer. In the early days, instead of having a single method 
__getitem__ which sometimes got a slice argument, there was two methods:

    obj[a] => obj.__getitem__(a)
    obj[a:b] => obj.__getslice__(a, b)
    obj[a:b:c] => obj.__getslice__(a, b, c)



-- 
Steven


More information about the Tutor mailing list