我正在寻找一种关于如何在 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)
这适用于 step of1
以及当最后一个寻址元素与 重合时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])
. 这不是一个选项,因为我需要反转切片本身。原因是我处理h5py
不允许step
切片中存在负值的数据集。一个简单但不是很优雅的方法是使用坐标列表,即
a[list(reversed(range(*s.indices(len(a)))))]
. 这也不是一个选项,因为h5py
要求列表中的索引必须按递增顺序给出。