Reputation: 6709
How do you reverse a Python string without omitting the start and end slice arguments?
word = "hello"
reversed_word = word[::-1]
I understand that this works, but how would I get the result by specifying the start and end indexes?
word = "hello"
reversed_word = word[?:?:-1]
It's hard to explain to students why word[::-1]
reverses a string. It's better if I can give them logical reasoning rather than "it's the pythonic way".
The way I explain word[::1]
is as follows: "You have not specified the start so it just starts from the start. You have not specified the end so it just goes until the end. Now the step is 1 so it just goes from the start to the end 1 character by 1." Now when my students see word[::-1]
they are going to think "We have not specified the start or the end so it will go through the string -1 characters at a time?"
Upvotes: 21
Views: 3056
Reputation: 105992
Some other ways to reverse a string:
word = "hello"
reversed_word1 = word[-1: :-1]
reversed_word2 = word[len(word)-1: :-1]
reversed_word3 = word[:-len(word)-1 :-1]
One thing you should note about the slicing notation a[i:j:k]
is that omitting i
and j
doesn't always mean that i
will become 0
and j
will become len(s)
. It depends upon the sign of k
. By default k
is +1
.
k
is +ve then the default value of i
is 0
(start from the beginning). If it is -ve then the default value of i
is -1
(start from the end). k
is +ve then the default value of j
is len(s)
(stop at the end). If it is -ve then the default value of j
is -(len(s)+1)
(stop at the beginning). Now you can explain your students how Hello[::-1]
prints olleH
.
Upvotes: 15
Reputation: 394825
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:
If step is positive:
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'
Upvotes: 4
Reputation: 20737
The notation string[begin:end:increment]
can be described with the following Python program:
def myreverse( string, begin, end, increment ):
newstring = ""
if begin >= 0 and end < 0:
begin = -1
for i in xrange(begin, end, increment):
try:
newstring += string[i]
except IndexError:
pass
return newstring
Upvotes: 2
Reputation: 1045
Not quite sure why, but the following will return the reverse of word
:
word = "hello"
word[len(word):-(len(word)+1):-1]
Or...
word = "hello"
word[len(word):-len(word)-1:-1]
Edit (Explanation):
From jedward's comment:
The middle parameter is the trickiest, but it's pretty straightforward once you realize (a) negative indices to slice start/stop indicate that you want to count "backwards" from the end of the string, and (b) the stop index is exclusive, so it will "count" up to but stop at/before the stop index. word[len(word):-len(word)-1:-1] is probably more clear.
In response to this comment:
The third value is actually the increment so you are telling Python that you want to start at the last letter then return all the (-1)st values up to the last one.
Here is an drawing (pulled together in a minute):
The drawing shows that we can also use this instead:
word = "hello"
word[-1:-len(word)-1:-1] #-1 as the first
Upvotes: 13
Reputation: 86128
In [27]: word
Out[27]: 'hello'
In [28]: word[-1:-6:-1]
Out[28]: 'olleh'
Why this works:
In [46]: word
Out[46]: 'hello'
In [47]: word[-1] # you want o to be your first value
Out[47]: 'o'
In [48]: word[-5] # you want h to be your last value
Out[48]: 'h'
In [49]: word[-1:-6:-1] # therefore ending point should be one
Out[49]: 'olleh' # past your last value that is -6
Upvotes: 3
Reputation:
If you do not specify a number for slice notation, Python will use None
as a default. So, you can just explicitly write the None
values:
>>> word = "hello"
>>> word[None:None:-1]
'olleh'
>>>
Upvotes: 4
Reputation: 4900
Recursive approach:
def reverse(word):
if len(word) <= 1:
return word
return reverse(word[1:]) + word[0]
Upvotes: 1