6

In looking at some python strings and functions, I discovered this strange quirk of python:

s = "hello"
print s[::-1]

which then prints: olleh

However, print s[len(s)-1:-1:-1] doesn't work. My understanding is that it should iterate from the last element s[len(s)-1] to the first element s[0]. However, it just prints an empty string '', which I believe is because in strings of some given length (say, 5), s[4] == s[-1]. But, I don't understand why python decides to use -1 instead of 4, which is the actual len(s).

Furthermore, s[len(s):0:-1] + s[0] works. Why is len(s) a valid index? Does python just convert len(s) to 0 arbitrarily?

P.S. This is in Python 2.7.8, I'm not sure if it also works in 3.x.x

EDIT: Confirmed to be the same in Python 3

Russia Must Remove Putin
  • 374,368
  • 89
  • 403
  • 331
Vasu
  • 1,090
  • 3
  • 18
  • 35

4 Answers4

6

The slice notation is this:

s[start:stop:step]

specifically, stop being up to but not including it. Translate this to what you're asking:

s[len(s)-1:-1:-1]

This is, based on the length of 5 for 'hello'

s[4:-1:-1]

or

s[4:4:-1]

which is an empty, or zero-length string.


I have given a much more in-depth exposition of the slice notation here: Explain Python's slice notation

Community
  • 1
  • 1
Russia Must Remove Putin
  • 374,368
  • 89
  • 403
  • 331
2

Negative indexes are counted from the end of the sequence, so you're just getting [-1:-1:-1], or equivalently [4:4:-1] which is zero-length string.

tcarobruce
  • 3,773
  • 21
  • 33
1

Remember that indexes start at 0, not 1.

[len(s)-1] gets the last letter ('o')

:-1 is just 'o' again, because you're getting the last value.

So then you want to go from the last value... to the last value... reversed (-1). Of course that will return an empty string.

To answer your second question, that's because no errors are ever raised when using index notation. Try doing print s[32489375:2784:-123]

TerryA
  • 58,805
  • 11
  • 114
  • 143
1

You are mapping backwards using a step of negative one. The default is:

from 0 to len(collection) by step

When you use a negative step the indices need to be reversed as well, or else you'll go the long way round. For example, from 0 to 5 by -1 goes: 0 + -1 = -1; -1 + -1 = -2 ... some time later an integer overflows ...)

In order to avoid this long walk around Python reverses the indices when step is negative and treats it as:

from len(collection) to 0 by step

This means that you need to deal with the start and end values in this case as negative integers from len(collection) - so, if you want to get the entire string in reverse, you are looking for:

s[-1:-(len(s) + 1):-1]

Or, in simpler terms:

from {the last item in the collection} to {the first item in the collection} by -1

This answer also has a good visual explanation for the indices.

Community
  • 1
  • 1
Sean Vieira
  • 155,703
  • 32
  • 311
  • 293