Eu tenho a seguinte lista Python (também pode ser uma tupla):
myList = ['foo', 'bar', 'baz', 'quux']
eu posso dizer
>>> myList[0:3]
['foo', 'bar', 'baz']
>>> myList[::2]
['foo', 'baz']
>>> myList[1::2]
['bar', 'quux']
Como escolho explicitamente itens cujos índices não têm padrões específicos? Por exemplo, eu quero selecionar [0,2,3]
. Ou, em uma lista muito grande de 1000 itens, desejo selecionar [87, 342, 217, 998, 500]
. Existe alguma sintaxe Python que faz isso? Algo parecido com:
>>> myBigList[87, 342, 217, 998, 500]
Respostas:
Eu comparei as respostas com python 2.5.2:
19,7 usec:
[ myBigList[i] for i in [87, 342, 217, 998, 500] ]
20,6 usec:
map(myBigList.__getitem__, (87, 342, 217, 998, 500))
22,7 usec:
itemgetter(87, 342, 217, 998, 500)(myBigList)
24,6 usec:
list( myBigList[i] for i in [87, 342, 217, 998, 500] )
Observe que no Python 3, o primeiro foi alterado para ser o mesmo que o quarto.
Outra opção seria começar com um
numpy.array
que permite a indexação por meio de uma lista ounumpy.array
:O
tuple
não funciona da mesma maneira que aquelas fatias.fonte
[myBigList[i] for i in [87, 342, 217, 998, 500]]
, mas eu gosto mais dessa abordagem.from operator import itemgetter
na parte de inicialização dopython -mtimeit
.myBigList[(87, 342, 217, 998, 500)]
que não funciona quandomyBigList
é um python regularlist
? Quando eu tento, eu entendoTypeError: list indices must be integers or slices, not tuple
. Isso seria muito mais fácil do que digitar a compreensão - há um problema de design / implementação de linguagem envolvido?lists
em Python só aceita inteiros ou fatias. Passar um número inteiro garante que apenas um item seja recuperado de uma lista existente. Passar uma fatia garante que uma parte dela seja recuperada, mas passar uma tupla é como passar um tipo de dados (tuple
) como um argumento para outro tipo de dados (list
) que é sintaticamente incorreto.Que tal isso:
fonte
operator
módulo!Não é integrado, mas você pode fazer uma subclasse de lista que considera as tuplas como "índices" se desejar:
impressão
fonte
Talvez seja necessária uma compreensão de lista:
Produz:
É isso que você está procurando?
fonte
Você também pode criar sua própria
List
classe que suporta tuplas como argumentos para__getitem__
se você quisermyList[(2,2,1,3)]
.fonte
operator
.len(myList)
overmyList.__len__()
.Eu só quero apontar, até mesmo a sintaxe do itemgetter parece muito legal, mas é meio lenta quando executada em uma lista grande.
Itemgetter levou 1.065209062149279
Múltiplas fatias levaram 0,6225321444745759
fonte
myList = np.array(range(1000000))
caso contrário, você obterá um erro.Outra solução possível:
fonte
como frequentemente, quando você tem uma matriz numpy booleana como
mask
[mylist[i] for i in np.arange(len(mask), dtype=int)[mask]]
Um lambda que funciona para qualquer sequência ou np.array:
subseq = lambda myseq, mask : [myseq[i] for i in np.arange(len(mask), dtype=int)[mask]]
newseq = subseq(myseq, mask)
fonte