2013-10-02 3 views
15

Насколько я могу судить, это официально не возможно, но есть ли «трюк» для доступа к произвольным непересекающимся элементам списка путем нарезки?Доступ к непоследовательным элементам списка или строки в 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

'a, b = L [2], L [5]'? – roippi

+0

@roippi - Это делает его простым, но я хотел применить его непосредственно к выходу функции, которая возвращает список, не вызывая функцию дважды или переписывая ее переменной, а затем захватывая. – beroe

+1

Я склонен сказать, что ваше понимание списка - лучшее, что вы можете сделать. Или, если вам не нужен фактический список, используйте выражение генератора, как в ответе Шашанка Гупта (хотя, если вам это нужно только один раз, вы можете просто ввести ген xp inline, а не выполнять функцию, чтобы вернуть его). – Blckknght

ответ

6

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

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) 

Путь функция работает, возвращая generator object, который можно перемещаться так же, как какой-либо последовательности Python.

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

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

И тогда вы могли бы вызвать функцию с:

select(L, [2, 5]) 

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

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

+0

Ах, это более независимо от любой внешней библиотеки, по сравнению с моим ответом. отлично сработано! – justhalf

+1

Считаете ли вы, что определение функции «select (lst, indices)» и вызов ее как «select (L, [2,5]) будет лучше? – justhalf

+0

@justhalf Да, это возможно, я сделаю заметку. – Shashank

7

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

+2

Это должен быть принятый ответ, который я чувствую. – Pramit

19

Вероятно, ближе всего к тому, что вы ищете 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) 
+0

Я очень удивлен, что этот ответ получает больше голосов, чем другие ответы. – justhalf

+2

@justhalf: Ну, 'itemgetter' очень похож на ответ Shashank, за исключением уже включенного в стандартную библиотеку Python. –

+0

Это хорошее решение, но я думаю, что дополнительные голоса - это потому, что он пришел немного раньше ... Я в конечном итоге выбрал тот, который не требует «импорта», хотя он в основном завертывает OP в определении функции , – beroe

2

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

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

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

["ABCDEF"[x] for x in [2,0,1]] 
['C', 'A', 'B'] 
Смежные вопросы