带有负跨度的序列开始处的扩展切片

在解释我的问题的同时忍受我。 如果您已了解扩展切片列表索引,请跳至粗体标题。

在python中,你可以使用切片符号来索引列表。 这是一个例子:

>>> A = list(range(10))
>>> A[0:5]
[0, 1, 2, 3, 4]

你也可以包含一个步幅,这就像一个“步骤”:

>>> A[0:5:2]
[0, 2, 4]

步幅也被允许为负数,这意味着元素以相反的顺序被检索:

>>> A[5:0:-1]
[5, 4, 3, 2, 1]

可是等等! 我想看看[4, 3, 2, 1, 0] 。 哦,我明白了,我需要减少开始和结束指数:

>>> A[4:-1:-1]
[]

发生了什么? 它将-1解释为数组的末尾,而不是开始。 我知道你可以做到这一点如下:

>>> A[4::-1]
[4, 3, 2, 1, 0]

但是你不能在所有情况下使用它。 例如,在一个已经通过索引的方法中。

我的问题是:

有没有什么好的pythonic方式使用扩展切片负向大步和明确的开始和结束索引,包括序列的第一个元素?

这是我到目前为止所提出的,但似乎并不令人满意。

>>> A[0:5][::-1]
[4, 3, 2, 1, 0]

改变startstop的语义很容易出错。 使用None-(len(a) + 1)而不是0-1 。 语义不是任意的。 参见Edsger W. Dijkstra的文章“为什么编号应该从零开始”。

>>> a = range(10)
>>> start, stop, step = 4, None, -1

要么

>>> start, stop, step = 4, -(len(a) + 1), -1
>>> a[start:stop:step]
[4, 3, 2, 1, 0]

要么

>>> s = slice(start, stop, step)
>>> a[s]
[4, 3, 2, 1, 0]

s是一个序列时,专门处理s[i:j:k]中的负指数:

如果ij是负数,则索引相对于字符串的末尾: len(s) + ilen(s) + j被替换。 但请注意-0仍然是0

这就是为什么len(range(10)[4:-1:-1]) == 0因为它等于range(10)[4:9:-1]


好的,我认为这可能和我一样好。 感谢Abgan激发了这个想法。 这依赖于切片中的None被视为缺少参数的事实。 任何人都有更好的?

def getReversedList(aList, end, start, step):
    return aList[end:start if start!=-1 else None:step]

编辑:检查start==-1 ,而不是0

这仍然不理想,因为你正在破坏-1的通常行为。 看来这里的问题是应该发生什么的两个重叠的定义。 无论谁赢取了另外有效的请求,寻找其他意图。


[ A[b] for b in range(end,start,stride) ]

更慢,但是你可以使用负指数,所以这应该工作:

[ A[b] for b in range(9, -1, -1) ]

我意识到这不是使用切片,但我认为我会提供解决方案,如果使用切片专门用于获得结果不是优先事项。

链接地址: http://www.djcxy.com/p/4523.html

上一篇: Extended slice that goes to beginning of sequence with negative stride

下一篇: How to make a copy of a 2D array in Python?