[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