-1

I created a string in python : 'HelpA' and labeled it as word.

>>>word='HelpA'

>>>word

'HelpA' #expected string

>>>word[0:4]

'Help' #expected string

While calling the word with negative indices, I am getting the full string instead of partial string as expected.

>>>word[-97:]

'HelpA'  #not the expected string

Its giving the whole string instead of expected string : 'pA' Why does this happen?

Vikranth Inti
  • 125
  • 5
  • 13
  • 10
    Why would you expect to get `pA` when indexing it with `[-97:]`? – Carles Mitjans May 23 '17 at 09:42
  • 1
    Where do you come up with the value `-97`? – kuro May 23 '17 at 09:42
  • 4
    in your example `word[0:4] == 'Help'`, not `'help'` – Azat Ibrakov May 23 '17 at 09:43
  • 1
    `-1` is the last element in the string, `-2` is the second to last, etc., with `-5` being the first character. And `-6` is out of bounds. What character in the string would then have index `-97`? – Some programmer dude May 23 '17 at 09:45
  • @CarlesMitjans, since there are 5 characters in the word, and 97=5*19+2, I am expecting the last 2 characters. – Vikranth Inti May 23 '17 at 09:47
  • 2
    @Babu: no, slicing indices do not wrap; they are instead bounded by the actual string indices. `len(word) - 97` is `-92`, which is then bound by the actual starting index `0`. – Martijn Pieters May 23 '17 at 09:48
  • @MartijnPieters, I now tried with >>> word[-100:] 'HelpA' >>> word[-99:] 'HelpA', Can u please explain it further? – Vikranth Inti May 23 '17 at 09:51
  • 1
    @Babu: negative indices are subtracted from `len(word)`. If that index then falls outside of the bounds, they are replaced by the bounds. For the start index, with a positive stride (the default), that means they are set to `0`. All those huge negative indices in the first position simply are replaced by `0`. `word[0:]` is the whole string. – Martijn Pieters May 23 '17 at 09:53
  • 2
    @MartijnPieters I'd say negative indices are **added** to `len(word)`. – Stefan Pochmann May 23 '17 at 09:55
  • 1
    @Babu: note that that subtraction only applies **once**. So `len(word) - 97` becomes `-92`. That is then *not treated as a relative index again*, it is simply out of bounds. – Martijn Pieters May 23 '17 at 09:55
  • 1
    @StefanPochmann: yeah, mathematically speaking, it is `len(word) + -97`. – Martijn Pieters May 23 '17 at 09:56

2 Answers2

6

It seems like you expect the negative index to 'wrap'. (97 % len(word) == 2).

It doesn't :)

This example shows you why:

>>> word[-1:]
'A'
>>> word[-3:]
'lpA'
>>> word[-5:]
'HelpA'
>>> word[-10:]
'HelpA'

When the negative index goes beyond the length of the string, it will be truncated. This section of the Python documentation explains explains it like this:

The slice of s from i to j is defined as the sequence of items with index k such that i <= k < j

This code does the equivalent slicing (for strings):

def slice(s, i, j):
    sliced = []
    for k, item in enumerate(s):
        if i <= k and k < j:
            sliced.append(item)
    return ''.join(sliced)

Output:

>>> slice('foo', -100, 2)
'fo'
>>> 'foo'[-100:2]
'fo'

This should make it clear why word[-100:] and word[-99:] gives the same result: all characters in the string have a position or index larger than -100 or -99, since 0 is the first position of the string

André Laszlo
  • 15,169
  • 3
  • 63
  • 81
2

You're asking for the last 97 characters. There aren't that many, but Python plays nice and just gives you as much as it can, which is the last 5 characters (i.e., all).

Stefan Pochmann
  • 27,593
  • 8
  • 44
  • 107