Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What are the default slice indices *really*?

Tags:

python

slice

From the python documentation docs.python.org/tutorial/introduction.html#strings:

Slice indices have useful defaults; an omitted first index defaults to zero, an omitted second index defaults to the size of the string being sliced.

For the standard case, this makes a lot of sense:

>>> s = 'mystring'
>>> s[1:]
'ystring'
>>> s[:3]
'mys'
>>> s[:-2]
'mystri'
>>> s[-1:]
'g'
>>> 

So far, so good. However, using a negative step value seems to suggest slightly different defaults:

>>> s[:3:-1]
'gnir'
>>> s[0:3:-1]
''
>>> s[2::-1]
'sym'

Fine, perhaps if the step is negative, the defaults reverse. An ommitted first index defaults to the size of the string being sliced, an omitted second index defaults to zero:

>>> s[len(s):3:-1]
'gnir'

Looking good!

>>> s[2:0:-1]
'sy'

Whoops. Missed that 'm'.

Then there is everyone's favorite string reverse statement. And sweet it is:

>>> s[::-1]
'gnirtsym'

However:

>>> s[len(s):0:-1]
'gnirtsy'

The slice never includes the value of the second index in the slice. I can see the consistency of doing it that way.

So I think I am beginning to understand the behavior of slice in its various permutations. However, I get the feeling that the second index is somewhat special, and that the default value of the second index for a negative step can not actually be defined in terms of a number.

Can anyone concisely define the default slice indices that can account for the provided examples? Documentation would be a huge plus.

like image 311
MikeG Avatar asked Sep 20 '12 22:09

MikeG


People also ask

What is the default value for slice step?

The default values are None , None , and None . The start , stop , and step parameters are used as the values of the slice object attributes of the same names.

What does ::- 1 mean in slicing?

So [::-1] means from 1st element to last element in steps of 1 in reverse order. If you have [start:stop] it's the same as step=1 . So [:-1] it means all but last. again it's the last element exclusive.

What are slice indices in Python?

Slicing in python means taking elements from one given index to another given index. We pass slice instead of index like this: [start:end] . We can also define the step, like this: [start:end:step] .

What is a slicing index?

Slicing is indexing syntax that extracts a portion from a list. If a is a list, then a[m:n] returns the portion of a : Starting with postion m. Up to but not including n. Negative indexing can also be used.


2 Answers

The end value is always exclusive, thus the 0 end value means include index 1 but not 0. Use None instead (since negative numbers have a different meaning):

>>> s[len(s)-1:None:-1]
'gnirtsym'

Note the start value as well; the last character index is at len(s) - 1; you may as well spell that as -1 (as negative numbers are interpreted relative to the length):

>>> s[-1:None:-1]
'gnirtsym'
like image 32
Martijn Pieters Avatar answered Nov 07 '22 15:11

Martijn Pieters


There actually aren't any defaults; omitted values are treated specially.

However, in every case, omitted values happen to be treated in exactly the same way as None. This means that, unless you're hacking the interpreter (or using the parser, ast, etc. modules), you can just pretend that the defaults are None (as recursive's answer says), and you'll always get the right answers.

The informal documentation cited isn't quite accurate—which is reasonable for something that's meant to be part of a tutorial. For the real answers, you have to turn to the reference documentation.

For 2.7.3, Sequence Types describes slicing in notes 3, 4, and 5.

For [i:j]:

… If i is omitted or None, use 0. If j is omitted or None, use len(s).

And for [i:j:k]:

If i or j are omitted or None, they become “end” values (which end depends on the sign of k). Note, k cannot be zero. If k is None, it is treated like 1.

For 3.3, Sequence Types has the exact same wording as 2.7.3.

like image 160
abarnert Avatar answered Nov 07 '22 15:11

abarnert