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