У меня есть следующий список Python (также может быть кортеж):
myList = ['foo', 'bar', 'baz', 'quux']
я могу сказать
>>> myList[0:3]
['foo', 'bar', 'baz']
>>> myList[::2]
['foo', 'baz']
>>> myList[1::2]
['bar', 'quux']
Как явно выбрать элементы, индексы которых не имеют определенных шаблонов? Например, я хочу выбрать [0,2,3]
. Или я хочу выбрать из очень большого списка из 1000 пунктов [87, 342, 217, 998, 500]
. Есть ли какой-нибудь синтаксис Python для этого? Что-то вроде:
>>> myBigList[87, 342, 217, 998, 500]
Ответы:
Я сравнил ответы с python 2.5.2:
19,7 мкс:
[ myBigList[i] for i in [87, 342, 217, 998, 500] ]
20,6 мкс:
map(myBigList.__getitem__, (87, 342, 217, 998, 500))
22,7 мкс:
itemgetter(87, 342, 217, 998, 500)(myBigList)
24,6 мкс:
list( myBigList[i] for i in [87, 342, 217, 998, 500] )
Обратите внимание, что в Python 3 1-й был изменен на 4-й.
Другой вариант - начать с a,
numpy.array
который позволяет индексировать через список илиnumpy.array
:Это
tuple
не работает так же, как срезы.источник
[myBigList[i] for i in [87, 342, 217, 998, 500]]
, но мне больше всего нравится этот подход.from operator import itemgetter
в части инициализацииpython -mtimeit
.myBigList[(87, 342, 217, 998, 500)]
не работает, когдаmyBigList
это обычный питонlist
? Когда я пытаюсь это сделать, я получаюTypeError: list indices must be integers or slices, not tuple
. Это было бы намного проще, чем печатать понимание - есть ли проблема с языковым дизайном / реализацией?lists
в Python принимают только целые числа или фрагменты. Передача целого числа гарантирует, что из существующего списка будет извлечен только один элемент. Передача фрагмента гарантирует, что его часть будет извлечена, но передача кортежа похожа на передачу типа данных (tuple
) в качестве аргумента другому типу данных (list
), который синтаксически неверен.Как насчет этого:
источник
operator
модуль!Он не является встроенным, но вы можете создать подкласс списка, который принимает кортежи как «индексы», если хотите:
печать
источник
Может быть, понимание списка в порядке:
Производит:
Это то, что вы ищете?
источник
Вы также можете создать свой собственный
List
класс, который поддерживает кортежи в качестве аргументов,__getitem__
если хотитеmyList[(2,2,1,3)]
.источник
operator
.len(myList)
overmyList.__len__()
.Я просто хочу отметить, что даже синтаксис itemgetter выглядит очень аккуратно, но при работе с большим списком он довольно медленный.
Itemgetter взял 1.065209062149279
Множественный срез занял 0,6225321444745759
источник
myList = np.array(range(1000000))
иначе вы получите ошибку.Другое возможное решение:
источник
как часто бывает, когда у вас есть логический массив numpy, например
mask
[mylist[i] for i in np.arange(len(mask), dtype=int)[mask]]
Лямбда, которая работает для любой последовательности или np.array:
subseq = lambda myseq, mask : [myseq[i] for i in np.arange(len(mask), dtype=int)[mask]]
newseq = subseq(myseq, mask)
источник