Я ищу общий метод, как перевернуть срез в 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])
. Это не вариант здесь, так как мне нужно изменить сам слайс. Причина в том, что я работаю с h5py
наборами данных, которые не допускают отрицательных значений step
в срезах.
Простым, но не очень элегантным способом было бы использование координатных списков, т.е. a[list(reversed(range(*s.indices(len(a)))))]
. Это также не вариант из-за требования h5py
, что индексы в списке должны указываться в возрастающем порядке.