Question or problem about Python programming:
I need to choose some elements from the given list, knowing their index. Let say I would like to create a new list, which contains element with index 1, 2, 5, from given list [-2, 1, 5, 3, 8, 5, 6]. What I did is:
a = [-2,1,5,3,8,5,6] b = [1,2,5] c = [ a[i] for i in b]
Is there any better way to do it? something like c = a[b] ?
How to solve the problem:
Solution 1:
You can use 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)
Or you can use 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]
But really, your current solution is fine. It’s probably the neatest out of all of them.
Solution 2:
Alternatives:
>>> map(a.__getitem__, b) [1, 5, 5]
>>> import operator >>> operator.itemgetter(*b)(a) (1, 5, 5)
Solution 3:
Another solution could be via pandas Series:
import pandas as pd a = pd.Series([-2, 1, 5, 3, 8, 5, 6]) b = [1, 2, 5] c = a[b]
You can then convert c back to a list if you want:
c = list(c)
Solution 4:
Basic and not very extensive testing comparing the execution time of the five supplied answers:
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]
using the following input:
a = range(0, 10000000) b = range(500, 500000)
simple python loop was the quickest with lambda operation a close second, mapIndexValues and getIndexValues were consistently pretty similar with numpy method significantly slower after converting lists to numpy arrays.If data is already in numpy arrays the numpyIndexValues method with the numpy.array conversion removed is quickest.
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
Solution 5:
I’m sure this has already been considered: If the amount of indices in b is small and constant, one could just write the result like:
c = [a[b[0]]] + [a[b[1]]] + [a[b[2]]]
Or even simpler if the indices itself are constants…
c = [a[1]] + [a[2]] + [a[5]]
Or if there is a consecutive range of indices…
c = a[1:3] + [a[5]]