我正在寻找一种通用的方法来反转Python中的切片。 我阅读了这篇详细的帖子,其中有几个关于切片操作的很好的解释: 理解Python的切片符号
然而,我无法找到一个通用的规则来计算反转的切片,该切片以完全相同的顺序地址相同的元素。我实际上很惊讶没有找到内置的方法来实现这一点。
我要寻找的是一种名为reversed_slice
的方法,其工作方式如下,包括负值的任意start
、stop
和step
值:
>>> import numpy as np
>>> a = np.arange(30)
>>> s = np.s_[10:20:2]
>>> a[s]
array([10, 12, 14, 16, 18])
>>> a[reversed_slice(s,len(a))]
array([18, 16, 14, 12, 10])
我尝试过但无法实现的方法是这样的:
def reversed_slice(slice_, len_):
"""
Reverses a slice (selection in array of length len_),
addressing the same elements in reverse order.
"""
assert isinstance(slice_, slice)
instart, instop, instep = slice_.indices(len_)
if instep > 0:
start, stop, step = instop - 1, instart - 1, -instep
else:
start, stop, step = instop + 1, instart + 1, -instep
return slice(start, stop, step)
这种方法在步骤为1
且最后一个地址元素与stop-1
重合时可以正常工作。但对于其他情况则不行:
>>> import numpy as np
>>> a = np.arange(30)
>>> s = np.s_[10:20:2]
>>> a[s]
array([10, 12, 14, 16, 18])
>>> a[reversed_slice(s,len(a))]
array([19, 17, 15, 13, 11])
所以似乎我缺少一些关系,如
(stop - start) % step
。
非常感谢提供一般方法的任何帮助。注意: - 我知道还有其他可能通过调用
reversed(a[s])
来获取具有相同元素反转的序列的方式。但这在此处不是一个选项,因为我需要反转切片本身。原因是我正在使用不允许在切片中使用负数 step
值的 h5py
数据集。
- 一个简单但不太优雅的方式是使用坐标列表,即 a[list(reversed(range(*s.indices(len(a)))))]
。由于列表中的索引必须按递增顺序给出,所以这也不是一个选项。
-2
在起始和结束位置是关键所在。它在这种情况下有效,即(20-10)%2 == 0
。然而,在其他情况下,它并不适用:a[11:20:2]
将会返回array([11, 13, 15, 17, 19])
,而a[20-2:11-2:-2]
将会返回array([18, 16, 14, 12, 10])
。 - eaglesearreversed_slice(np.s_[10:20:2])
将得到slice(20, 10, -2)
,这将给出array([20, 18, 16, 14, 12])
。 - eaglesears = np.s_[-2:10:-2]
,a[s]
得到的结果是array([28, 26, 24, 22, 20, 18, 16, 14, 12])
,但是reversed_slice(s)
得到的结果是slice(12, 0, 2)
和一个空数组。 - eaglesear