Доступ к непоследовательным элементам списка или строки в python

Насколько я могу судить, это официально не возможно, но есть ли "трюк" для доступа к произвольным непоследовательным элементам списка путем разрезания?

Например:

>>> L = range(0,101,10)
>>> L
[0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100]

Теперь я хочу иметь возможность делать

a,b = L[2,5]

так что a == 20 и b == 50

Один из способов, кроме двух утверждений, был бы таким глупым:

a,b = L[2:6:3][:2]

Но это не распространяется на нерегулярные интервалы.

Может быть, с пониманием списка с использованием индексов, которые я хочу?

[L[x] for x in [2,5]]

Я хотел бы знать, что рекомендуется для этой общей проблемы.

Ответы

Ответ 1

Что-то вроде этого?

def select(lst, *indices):
    return (lst[i] for i in indices)

Использование:

>>> def select(lst, *indices):
...     return (lst[i] for i in indices)
...
>>> L = range(0,101,10)
>>> a, b = select(L, 2, 5)
>>> a, b
(20, 50)

Способ работы функции заключается в возврате объекта генератора который может быть повторен аналогично любому типу последовательности Python.

Как отмечалось в комментариях @justhalf, ваш синтаксис вызова может быть изменен так, как вы определяете параметры функции.

def select(lst, indices):
    return (lst[i] for i in indices)

И тогда вы можете вызвать функцию с помощью:

select(L, [2, 5])

или любой список по вашему выбору.

Обновление. Теперь я рекомендую использовать operator.itemgetter, если вам не нужна ленивая функция оценки генераторов. См. Ответ Джона Y.

Ответ 2

Вероятно, ближайший к тому, что вы ищете, itemgetter:

>>> L = range(0, 101, 10)
>>> L
[0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100]
>>> from operator import itemgetter
>>> itemgetter(2, 5)(L)
(20, 50)

Ответ 3

Если вы можете использовать numpy, вы можете сделать именно это:

>>> import numpy
>>> the_list = numpy.array(range(0,101,10))
>>> the_indices = [2,5,7]
>>> the_subset = the_list[the_indices]
>>> print the_subset, type(the_subset)
[20 50 70] <type 'numpy.ndarray'>
>>> print list(the_subset)
[20, 50, 70]

numpy.array очень похож на list, просто поддерживает большее количество операций, таких как математические операции, а также произвольный выбор индекса, например мы видим здесь.

Ответ 4

Просто для полноты, метод из исходного вопроса довольно прост. Вы захотите обернуть его в функцию, если L является самой функцией или назначить результат функции переменной заранее, поэтому она не будет вызываться повторно:

[L[x] for x in [2,5]]

Конечно, он также будет работать для строки...

["ABCDEF"[x] for x in [2,0,1]]
['C', 'A', 'B']