views:

246

answers:

3

I would like to index a list with another list like this

L = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']
Idx = [0, 3, 7]
T = L[ Idx ]

and T should end up being a list containing ['a', 'd', 'h'].

Is there a better way than

T = []
for i in Idx:
    T.append(L[i])

print T
# Gives result ['a', 'd', 'h']
+30  A: 
T = [L[i] for i in Idx]
van
Is this faster than a for-loop or only shorter?
Daniel Andrén
@daniel: both + recommended
SilentGhost
A quick timing test (no pysco or anything, so make of it what you will) showed the list comprehension 2.5x faster than the loop (1000 elements, repeated 10000 times).
James Hopkin
(using map and a lambda is even slower - to be expected, since it calls a function for each iteration)
James Hopkin
+1 If the indexing list is arbitrary, then a list comrpehension is the way. I think though that, when possible, which seems not to be the case here, slices are even faster.
Jaime
+2  A: 
T = map(lambda i: L[i], Idx)
Mehrdad Afshari
needed to be converted to list in py3k
SilentGhost
+4  A: 

If you are using numpy, you can perform extended slicing like that:

>>> import numpy
>>> a=numpy.array(['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'])
>>> Idx = [0, 3, 7]
>>> a[Idx]
array(['a', 'd', 'h'], 
      dtype='|S1')

...and is probably much faster (if performance is enough of a concern to to bother with the numpy import)

bpowah