Доступ к непоследовательным элементам списка или строки в 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]]

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

5 ответов


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

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.


вероятно, ближе всего к тому, что вы ищете, это itemgetter (или здесь для Python 2 docs):

>>> L = list(range(0, 101, 10))  # works in Python 2 or 3
>>> L
[0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100]
>>> from operator import itemgetter
>>> itemgetter(2, 5)(L)
(20, 50)

если вы можете использовать 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, просто он поддерживает больше операций, таких как математические операции, а также произвольный выбор индекса, как мы видим здесь.


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

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

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

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

ни один из других ответов не будет работать для многомерного объекта нарезки. IMHO это самое общее решение (использует numpy):

numpy.ix_ позволяет выбирать произвольные индексы во всех измерениях массива одновременно.

например:

>>> a = np.arange(10).reshape(2, 5) # create an array
>>> a
array([[0, 1, 2, 3, 4],
       [5, 6, 7, 8, 9]])
>>> ixgrid = np.ix_([0, 1], [2, 4]) # create the slice-like grid
>>> ixgrid
(array([[0],
       [1]]), array([[2, 4]]))
>>> a[ixgrid]                       # use the grid to slice a
array([[2, 4],
       [7, 9]])