Получить индексы, выбранные при нарезке списка

У меня есть список:

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]

Я исправил присваивание s таким образом, чтобы его использование действительно давало соответствующий результат. slice(-2, 0, None) не работает; это было бы эквивалентно попытке things[-2:0], которая дает пустой результат.

Karl Knechtel 02.06.2023 03:43

Может list(range(len(things))][s])?

Ynjxsjmh 02.06.2023 03:43

Это не сработает для примера, где объект среза имеет шаг.

TheLazyScripter 02.06.2023 03:56

@TheLazyScripter, насколько я могу судить, работает просто отлично, как и все мои предложения.

Karl Knechtel 02.06.2023 04:05

Связано (ответ почти идентичен, но вопрос имеет совершенно другую направленность): Получить длину среза из объекта среза в Python

ShadowRanger 02.06.2023 04:14
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
5
56
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Именно в этом заключается цель метода 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], когда размер среза намного меньше размера входного списка.

blhsing 02.06.2023 03:55

Метод indices на самом деле здесь бесполезен, и ваш "в сторону" - это фактический ответ...

Kelly Bundy 02.06.2023 04:39

Конечно, для запрошенного выходного формата; но люди часто запрашивают неправильный результат, потому что они просто не рассмотрели возможности.

Karl Knechtel 02.06.2023 04:43

Даже если это так (а я в этом сомневаюсь), я бы сказал, что у вас все еще есть обратная сторона. Вопрос в том, что это такое, и это разумно. Я думаю, что ваш текущий «в сторону» должен быть первым, а метод indices может быть в стороне после него.

Kelly Bundy 02.06.2023 04:46

Другие вопросы по теме