Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
481 views
in Technique[技术] by (71.8m points)

python - Extended slice that goes to beginning of sequence with negative stride

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.

My question is:

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]
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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 or j is negative, the index is relative to the end of the string: len(s) + i or len(s) + j is substituted. But note that -0 is still 0.

that is why len(range(10)[4:-1:-1]) == 0 because it is equivalent to range(10)[4:9:-1].


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...