8

let's say I have a string:

>>>a = 'akwkwas'
>>>
>>>a[-3:]
'was'
>>>a[-3:None]
'was'
>>>a[-3:0]
''

why can't I use 0 as the end of the slice?

this is from docs:

One way to remember how slices work is to think of the indices as pointing between characters, with the left edge of the first character numbered 0. Then the right edge of the last character of a string of n characters has index n, for example:

 +---+---+---+---+---+---+
 | P | y | t | h | o | n |
 +---+---+---+---+---+---+
 0   1   2   3   4   5   6
-6  -5  -4  -3  -2  -1

The first row of numbers gives the position of the indices 0...6 in the string; the second row gives the corresponding negative indices. The slice from i to j consists of all characters between the edges labeled i and j, respectively.

so when we use negative indices in loop , we should check the end's value, beacuse the end 0 in negative indices does not exist, such as when we split a string to a money-like string:

>>>a = '12349878334'
>>>print(','.join([a[-i-3:-i if i else None] for i in range(0, len(a), 3)][::-1])) 
>>>12,349,878,334
Sinux
  • 1,728
  • 3
  • 15
  • 28

5 Answers5

7

0 is the start of the sequence. Always, unambiguously. Changing its meaning to sometimes be the end would lead to a lot of confusion, especially when using variables for those two values.

Using negative indices is also not a different mode; negative indices are converted to positive indices relative to the length. Changing what element 0 refers to because the other slice input (start or stop) was a negative number makes no sense.

Because 0 always means the first element of the sequence, and there is no spelling for a negative zero, you cannot use 0 to mean the end of the sequence.

You can use None as the stop element to mean this instead, if you need to parameterise your indices:

start = -3
stop = None
result = a[start:stop]

You can also create a slice() object; the same rules apply for how indices are interpreted:

indices = slice(-3, None)
result = a[indices]

In fact, the interpreter translates the slice notation into a slice() object, which is then passed to the object to distinguish from straight-up indexing with a single integer; the a[start:stop] notation translates to type(a).__getitem__(a, slice(start, stop)) whereas a[42] becomes type(a).__getitem__(a, 42).

So by using a slice() object you can record either slicing or single-element indexing with a single variable.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
  • Great answer! In my specific case of either including or not including the last element, I ended up setting stop = None if includeLast else -1. That way I didn't have to add a length, which was potentially unknown, because this was on a TensorFlow Tensor, not a Python list. The solution worked. Thanks! :-) – Elias Hasle May 08 '19 at 11:01
1

It is boring to use negative slice in a loop if there is some chance to slice to 'negative zero', because [:-0] is not interpreted as expected.

But there is a simple way to solve the problem, just convert negative index to positive index by adding the length of the container.

E.g. Negative Slice Loop:

a = np.arange(10)
for i in range(5):
    print(a[5-i:-i])

Answer:

[]
[4 5 6 7 8]
[3 4 5 6 7]
[2 3 4 5 6]
[1 2 3 4 5]

Convert to positive by adding the lenght:

for i in range(5):
    print(a[5-i:len(a)-i])

Get the right answer:

[5 6 7 8 9]
[4 5 6 7 8]
[3 4 5 6 7]
[2 3 4 5 6]
[1 2 3 4 5]
吕廷博
  • 56
  • 1
  • 4
0

Because you can not use duplicate indices for slicing, since the index of the start of string is 0 it may be cause a confusion.

Suppose if you want to get a slice from leading to trailing then you shall do :

my_string[0:0]  

which returns an empty string.

>>> my_string='example'
>>> my_string[0:0]
''
>>>

For more info about python slicing see https://docs.python.org/2.3/whatsnew/section-slices.html

Mazdak
  • 105,000
  • 18
  • 159
  • 188
  • 1
    Actually look at this `>>> a[-3:0:-1] 'wkwk' >>> a[1:3:-1] '' >>> a[1:3] 'kw' >>> a[-1:3] '' >>> a[-1:3:-1] 'saw'` I think it is because the index is going from positive to negative – The6thSense Jul 31 '15 at 07:28
0

Because -3 as same as 4, which larger than 0:

In [8]: a = 'akwkwas'

In [9]: a[-3:]
Out[9]: 'was'

In [10]: a[4:]
Out[10]: 'was'

In [11]: a[4:0]
Out[11]: ''
lqhcpsgbl
  • 3,694
  • 3
  • 21
  • 30
0

Looking at your variable:

a = 'was'

You already know that 'w' is at position 0 and it is also at position -3.

When you write a[0:-3] are telling Python to slice the string starting at index 0 and go until index 0.

Remember that the 2nd argument is telling Python which index to stop at and not include. That argument in exclusive where as the first argument is inclusive.

Eric Bulloch
  • 827
  • 6
  • 10
  • It's just a example man. I have another example which shows that using negative indices if more handy – Sinux Jul 31 '15 at 07:40