Understanding string reversal via slicing
Sure, the [::]
is the extended slice operator. It allows you to take substrings. Basically, it works by specifying which elements you want as [begin:end:step], and it works for all sequences. Two neat things about it:
- You can omit one or more of the elements and it does "the right thing"
- Negative numbers for begin, end, and step have meaning
For begin and end, if you give a negative number, it means to count from the end of the sequence. For instance, if I have a list:
l = [1,2,3]
Then l[-1]
is 3, l[-2]
is 2, and l[-3]
is 1.
For the step
argument, a negative number means to work backwards through the sequence. So for a list::
l = [1,2,3,4,5,6,7,8,9,10]
You could write l[::-1]
which basically means to use a step size of -1 while reading through the list. Python will "do the right thing" when filling in the start and stop so it iterates through the list backwards and gives you [10,9,8,7,6,5,4,3,2,1]
.
I've given the examples with lists, but strings are just another sequence and work the same way. So a[::-1]
means to build a string by joining the characters you get by walking backwards through the string.
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
How do I reverse a string in Python?
Using slicing:
>>> 'hello world'[::-1]
'dlrow olleh'
Slice notation takes the form [start:stop:step]
. In this case, we omit the start
and stop
positions since we want the whole string. We also use step = -1
, which means, "repeatedly step from right to left by 1 character".
Logic behind Python reversing a slice with index and step
It is not the case that the first number has to be less than the second, it just is the starting index, while the second is the ending index. Therefore, when you are going backwards (third index is -1), the starting index should be larger than the ending index, otherwise you'll get an empty string.
Python reverse-stride slicing
Simply exclude the end range index...
>>> foo[3::-1]
'3210'
Ironically, about the only option I think you didn't try.
slicing to reverse string confusion
In Python list indexes, the index -1
refers to the last character in the string. When using a negative step index, omitting the start index uses -1
as the start (a positive step index starts at 0
by default).
Reverse a Python string without omitting start and end slice
From the Python 2 source, this is defined with ternary expressions:
defstart = *step < 0 ? length-1 : 0;
defstop = *step < 0 ? -1 : length;
So, when start and stop are not given,
If step is negative:
- start is length - 1
- stop is -1, (this is the C index, tricky to implement in Python, must be -length-1)
If step is positive:
- start is 0
- stop is length
So to answer this question:
How would I get the result by specifying the start and end indexes?
To specify this yourself, use e.g. the following (put into a function for reusability)
def my_slice(word, step):
'''slice word with only step'''
start = len(word)-1 if step < 0 else 0
stop = -len(word)-1 if step < 0 else len(word)
return word[start:stop:step]
word = "hello"
step = -1
my_slice(word, step)
returns
'olleh'
Related Topics
How to Make an Image with a Transparent Backround in Pygame
How to Show Explosion Image When Collision Happens
Why Do Many Examples Use 'Fig, Ax = Plt.Subplots()' in Matplotlib/Pyplot/Python
How to Use Python to Get the System Hostname
Appending Item to Lists Within a List Comprehension
Substitute Multiple Whitespace with Single Whitespace in Python
How to Check If a Column Exists in Pandas
Python and Openssl Version Reference Issue on Os X
How to Remove Duplicate Words in a String with Python
Skip Multiple Iterations in Loop
Error "Importerror: Dll Load Failed: %1 Is Not a Valid Win32 Application"
How to Invoke Pandas.Rolling.Apply with Parameters from Multiple Column