Bear with me while I explain my question. Skip down to the bold heading if you already understand extended slice list indexing.
In python, you can index lists using slice notation. Here's an example:
>>> A = list(range(10))
>>> A[0:5]
[0, 1, 2, 3, 4]
You can also include a stride, which acts like a "step":
>>> A[0:5:2]
[0, 2, 4]
The stride is also allowed to be negative, meaning the elements are retrieved in reverse order:
>>> A[5:0:-1]
[5, 4, 3, 2, 1]
But wait! I wanted to see [4, 3, 2, 1, 0]
. Oh, I see, I need to decrement the start and end indices:
>>> A[4:-1:-1]
[]
What happened? It's interpreting -1 as being at the end of the array, not the beginning. I know you can achieve this as follows:
>>> A[4::-1]
[4, 3, 2, 1, 0]
But you can't use this in all cases. For example, in a method that's been passed indices.
Is there any good pythonic way of using extended slices with negative strides and explicit start and end indices that include the first element of a sequence?
This is what I've come up with so far, but it seems unsatisfying.
>>> A[0:5][::-1]
[4, 3, 2, 1, 0]
You can slice sequences to create new sequences of the same type containing subsets of the original elements. Slice operations can modify mutable sequences—those that do not modify a sequence work identically for lists, tuples and strings.
The slice syntax is a handy way to refer to sub-parts of sequences – typically strings and lists. The slice s[start:end] is the elements beginning at start and extending up to but not including end.
Definition and Usage The slice() function returns a slice object. A slice object is used to specify how to slice a sequence. You can specify where to start the slicing, and where to end. You can also specify the step, which allows you to e.g. slice only every other item.
The basic syntax for a slice is square brackets with colons and integers inside "[0:1:2]".
It is error-prone to change the semantics of start
and stop
. Use None
or -(len(a) + 1)
instead of 0
or -1
. The semantics is not arbitrary. See Edsger W. Dijkstra's article "Why numbering should start at zero".
>>> a = range(10)
>>> start, stop, step = 4, None, -1
Or
>>> start, stop, step = 4, -(len(a) + 1), -1
>>> a[start:stop:step]
[4, 3, 2, 1, 0]
Or
>>> s = slice(start, stop, step)
>>> a[s]
[4, 3, 2, 1, 0]
When s
is a sequence the negative indexes in s[i:j:k]
are treated specially:
If
i
orj
is negative, the index is relative to the end of the string:len(s) + i
orlen(s) + j
is substituted. But note that-0
is still0
.
that is why len(range(10)[4:-1:-1]) == 0
because it is equivalent to range(10)[4:9:-1]
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With