python list indexing elements

subplot python



Acceda a múltiples elementos de la lista conociendo su índice (6)

Alternativas:

>>> map(a.__getitem__, b) [1, 5, 5]

>>> import operator >>> operator.itemgetter(*b)(a) (1, 5, 5)

Necesito elegir algunos elementos de la lista dada, conociendo su índice. Digamos que me gustaría crear una nueva lista, que contiene elementos con el índice 1, 2, 5, de la lista dada [-2, 1, 5, 3, 8, 5, 6]. Lo que hice fue:

a = [-2,1,5,3,8,5,6] b = [1,2,5] c = [ a[i] for i in b]

¿Hay alguna forma mejor de hacerlo? algo así como c = a [b]?


Estoy seguro de que esto ya se ha considerado: si la cantidad de índices en b es pequeña y constante, uno podría simplemente escribir el resultado como:

c = [a[b[0]]] + [a[b[1]]] + [a[b[2]]]

O incluso más simple si los índices en sí son constantes ...

c = [a[1]] + [a[2]] + [a[5]]

O si hay un rango consecutivo de índices ...

c = a[1:3] + [a[5]]


Mi respuesta no usa colecciones numpy o python.

Una forma trivial de encontrar elementos sería la siguiente:

a = [-2, 1, 5, 3, 8, 5, 6] b = [1, 2, 5] c = [i for i in a if i in b]

Drawback: este método puede no funcionar para listas más grandes. Se recomienda usar numpy para listas más grandes.


Otra solución podría ser a través de pandas Series:

import pandas as pd a = pd.Series([-2, 1, 5, 3, 8, 5, 6]) b = [1, 2, 5] c = a[b]

A continuación, puede convertir c en una lista si lo desea:

c = list(c)


Pruebas básicas y no muy extensas que comparan el tiempo de ejecución de las cinco respuestas proporcionadas:

def numpyIndexValues(a, b): na = np.array(a) nb = np.array(b) out = list(na[nb]) return out def mapIndexValues(a, b): out = map(a.__getitem__, b) return list(out) def getIndexValues(a, b): out = operator.itemgetter(*b)(a) return out def pythonLoopOverlap(a, b): c = [ a[i] for i in b] return c multipleListItemValues = lambda searchList, ind: [searchList[i] for i in ind]

usando la siguiente entrada:

a = range(0, 10000000) b = range(500, 500000)

el bucle python simple fue el más rápido con operación lambda un segundo cercano, mapIndexValues ​​y getIndexValues ​​fueron bastante similares con el método numpy significativamente más lento después de convertir listas en matrices numpy. Si los datos ya están en matrices numpy, el método numpyIndexValues ​​con la conversión numpy.array eliminada es el más rápido

numpyIndexValues -> time:1.38940598 (when converted the lists to numpy arrays) numpyIndexValues -> time:0.0193445 (using numpy array instead of python list as input, and conversion code removed) mapIndexValues -> time:0.06477512099999999 getIndexValues -> time:0.06391049500000001 multipleListItemValues -> time:0.043773591 pythonLoopOverlap -> time:0.043021754999999995


Puede usar operator.itemgetter :

from operator import itemgetter a = [-2, 1, 5, 3, 8, 5, 6] b = [1, 2, 5] print itemgetter(*b)(a) # Result: (1, 5, 5)

O puede usar numpy :

import numpy as np a = np.array([-2, 1, 5, 3, 8, 5, 6]) b = [1, 2, 5] print list(a[b]) # Result: [1, 5, 5]

Pero realmente, tu solución actual está bien. Es probablemente el mejor de todos ellos.