How to explain the reverse of a sequence by slice notation a[::-1]
I think the docs are perhaps a little misleading on this, but the optional arguments of slicing if omitted are the same as using None
:
>>> a = "hello"
>>> a[::-1]
'olleh'
>>> a[None:None:-1]
'olleh'
You can see that these 2 above slices are identical from the CPython bytecode:
>>> import dis
>>> dis.dis('a[::-1]') # or dis.dis('a[None:None:-1]')
1 0 LOAD_NAME 0 (a)
3 LOAD_CONST 0 (None)
6 LOAD_CONST 0 (None)
9 LOAD_CONST 2 (-1)
12 BUILD_SLICE 3
15 BINARY_SUBSCR
16 RETURN_VALUE
For a negative step
, the substituted values for None
are len(a) - 1
for the start
and -len(a) - 1
for the end
:
>>> a[len(a)-1:-len(a)-1:-1]
'olleh'
>>> a[4:-6:-1]
'olleh'
>>> a[-1:-6:-1]
'olleh'
This may help you visualize it:
h e l l o
0 1 2 3 4 5
-6 -5 -4 -3 -2 -1
a[0:5:-1]
does not make much sense, since when you use this notation the indices mean: a[start:end:step]
. When you use a negative step your end value needs to be at an "earlier" position than your start value.
All it does is slice. You pick. start stop and step so basically you're saying it should start at the beginning until the beginning but going backwards (-1).
If you do it with -2 it will skip letters:
>>> a[::-2]
'olh'
When doing [0:5:-1]
your'e starting at the first letter and going back directly to 5 and thus it will stop. only if you try [-1::-1]
will it correctly be able to go to the beginning by doing steps of negative 1.
Edit to answer comments
As pointed out the documentation says
an omitted second index defaults to the size of the string being sliced.
Lets assume we have str
with len(str) = 5
. When you slice the string and omit, leave out, the second number it defaults to the length of the string being sliced, in this case - 5.
i.e str[1:] == str[1:5]
, str[2:] == str[2:5]
. The sentence refers to the length of the original object and not the newly sliced object.
Also, this answer is great
You are confused with the behavior of the stepping. To get the same result, what you can do is:
a[0:5][::-1]
'olleh'
Indeed, stepping wants to 'circle' around backwards in your case, but you are limiting it's movement by calling a[0:5:-1]
.