У меня есть список:
things = ["a", "b", "c", "d", "e", "f"]
У меня также есть объект фрагмента, предназначенный для списка выше. Вот пример:
s = slice(-2, None, None)
print(things[-2:]) # ['e', 'f']
Моя цель — извлечь конкретные индексы, на которые влияет срез. В этом примере это будет:
[4, 5]
Кто-нибудь знает, как я буду делать это более питонически? Мое текущее решение:
print([i for i in range(len(things))][s]) # [4, 5]
Может list(range(len(things))][s])?
Это не сработает для примера, где объект среза имеет шаг.
@TheLazyScripter, насколько я могу судить, работает просто отлично, как и все мои предложения.
Связано (ответ почти идентичен, но вопрос имеет совершенно другую направленность): Получить длину среза из объекта среза в Python






Именно в этом заключается цель метода indices класса slice.
Как поясняется во встроенной справке:
Help on built-in function indices:
indices(...) method of builtins.slice instance
S.indices(len) -> (start, stop, stride)
Assuming a sequence of length len, calculate the start and stop
indices, and the stride length of the extended slice described by
S. Out of bounds indices are clipped in a manner consistent with the
handling of normal slices.
Таким образом, передайте ему длину последовательности, которая будет нарезана, чтобы получить соответствующие значения начала/остановки/шага:
>>> s = slice(-2, None, None)
>>>
>>> things = ['a', 'b', 'c', 'd', 'e', 'f']
>>> things[s]
['e', 'f']
>>> s.indices(len(things))
(4, 6, 1)
>>> x, y, z = s.indices(len(things))
>>> things[x:y:z]
['e', 'f']
Что, конечно, можно использовать для построения соответствующих range значений:
>>> list(range(*s.indices(len(things))))
[4, 5]
Кроме того, объекты range можно индексировать и нарезать напрямую, а преобразовать их в списки так же просто, как передать их непосредственно типу list. Таким образом:
>>> list(range(len(things))[s])
[4, 5]
>>> list(range(len(things)))[s]
[4, 5]
Это проще для получения фактического списка индексов; в других контекстах (например, при реализации __getitem__ для пользовательского типа) значения старт/стоп/шаг могут быть более полезными.
Стоит отметить, что list(range(len(things))[s]) намного эффективнее, чем list(range(len(things)))[s], когда размер среза намного меньше размера входного списка.
Метод indices на самом деле здесь бесполезен, и ваш "в сторону" - это фактический ответ...
Конечно, для запрошенного выходного формата; но люди часто запрашивают неправильный результат, потому что они просто не рассмотрели возможности.
Даже если это так (а я в этом сомневаюсь), я бы сказал, что у вас все еще есть обратная сторона. Вопрос в том, что это такое, и это разумно. Я думаю, что ваш текущий «в сторону» должен быть первым, а метод indices может быть в стороне после него.
Я исправил присваивание
sтаким образом, чтобы его использование действительно давало соответствующий результат.slice(-2, 0, None)не работает; это было бы эквивалентно попыткеthings[-2:0], которая дает пустой результат.