2012-08-07 15 views
26

En Python tengo una lista de elementos aList y una lista de índices myIndices. ¿Hay alguna forma de que pueda recuperar todos los elementos en aList teniendo como índices los valores en myIndices?Python: listas de filtrado por índices

Ejemplo:

>>> aList = ['a', 'b', 'c', 'd', 'e', 'f', 'g'] 
>>> myIndices = [0, 3, 4] 
>>> aList.A_FUNCTION(myIndices) 
['a', 'd', 'e'] 
+7

'[aList [i] para i en myIndices]' – Morwenn

+3

Si sólo desea iterar sobre los elementos, propongo utilizar una expresión generadora vez : '(lista [i] para i en myIndices)' – hochl

Respuesta

52

No sé cualquier método para hacerlo. Sin embargo, se puede utilizar un list comprehension:

>>> [aList[i] for i in myIndices] 
9

Definitivamente el uso de una lista por comprensión pero aquí es una función que lo hace (no existen métodos de list que hacer esto). Sin embargo, este es un mal uso de itemgetter, pero solo por el conocimiento, he publicado esto.

>>> from operator import itemgetter 
>>> a_list = ['a', 'b', 'c', 'd', 'e', 'f', 'g'] 
>>> my_indices = [0, 3, 4] 
>>> itemgetter(*my_indices)(a_list) 
('a', 'd', 'e') 
+0

Creo que este no es el caso correcto para usa 'itemgetter'. –

+0

@BasicWolf Sí, no debería usarlo, pero el OP solicitó una función que pudiera hacer esto, así que solo mostré lo que es. Haré que sea más explícito que no deberías usar esto. – jamylak

+0

Creo que esto también estará limitado por el límite de la cantidad máxima de argumentos que una función puede tener. – Paddy3118

5

La indexación por listas se puede hacer en numpy. Convertir su lista de base a una matriz numpy y luego aplicar otra lista como un índice:

>>> from numpy import array 
>>> array(aList)[myIndices] 
array(['a', 'd', 'e'], 
    dtype='|S1') 

Si necesita, convertir de nuevo a una lista al final:

>>> from numpy import array 
>>> a = array(aList)[myIndices] 
>>> list(a) 
['a', 'd', 'e'] 

En algunos casos esta solución puede ser más conveniente que la comprensión de la lista.

1

que no estaba contento con estas soluciones, así que creé una clase Flexlist que simplemente extiende la clase list, y permite un ajuste flexible por entero, rebanada o el índice de lista:

class Flexlist(list): 
    def __getitem__(self, keys): 
     if isinstance(keys, (int, slice)): return list.__getitem__(self, keys) 
     return [self[k] for k in keys] 

Entonces, por tu ejemplo, se podría utilizar con:

aList = Flexlist(['a', 'b', 'c', 'd', 'e', 'f', 'g']) 
myIndices = [0, 3, 4] 
vals = aList[myIndices] 

print(vals) # ['a', 'd', 'e'] 
+0

Esto es bastante útil. – mikeTronix

4

usted podría utilizar map

map(aList.__getitem__, myIndices) 

o operator.itemgetter

f = operator.itemgetter(*aList) 
f(myIndices) 
2

Si no se requiere una lista con acceso simultáneo a todos los elementos, pero sólo desea utilizar todos los elementos de la sub-lista de forma iterativa (o pasarlos a algo que lo hará), es más eficaz utilizar una expresión del generador en lugar de lista por comprensión:

(aList[i] for i in myIndices) 
Cuestiones relacionadas