I have the following Python list (can also be a tuple):
myList = ['foo', 'bar', 'baz', 'quux'] I can say
>>> myList[0:3] ['foo', 'bar', 'baz'] >>> myList[::2] ['foo', 'baz'] >>> myList[1::2] ['bar', 'quux'] How do I explicitly pick out items whose indices have no specific patterns? For example, I want to select [0,2,3]. Or from a very big list of 1000 items, I want to select [87, 342, 217, 998, 500]. Is there some Python syntax that does that? Something that looks like:
>>> myBigList[87, 342, 217, 998, 500] 28 Answers
list( myBigList[i] for i in [87, 342, 217, 998, 500] ) I compared the answers with 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] )
Note that in Python 3, the 1st was changed to be the same as the 4th.
Another option would be to start out with a numpy.array which allows indexing via a list or a numpy.array:
>>> import numpy >>> myBigList = numpy.array(range(1000)) >>> myBigList[(87, 342, 217, 998, 500)] Traceback (most recent call last): File "<stdin>", line 1, in <module> IndexError: invalid index >>> myBigList[[87, 342, 217, 998, 500]] array([ 87, 342, 217, 998, 500]) >>> myBigList[numpy.array([87, 342, 217, 998, 500])] array([ 87, 342, 217, 998, 500]) The tuple doesn't work the same way as those are slices.
What about this:
from operator import itemgetter itemgetter(0,2,3)(myList) ('foo', 'baz', 'quux') 1Maybe a list comprehension is in order:
L = ['a', 'b', 'c', 'd', 'e', 'f'] print [ L[index] for index in [1,3,5] ] Produces:
['b', 'd', 'f'] Is that what you are looking for?
It isn't built-in, but you can make a subclass of list that takes tuples as "indexes" if you'd like:
class MyList(list): def __getitem__(self, index): if isinstance(index, tuple): return [self[i] for i in index] return super(MyList, self).__getitem__(index) seq = MyList("foo bar baaz quux mumble".split()) print seq[0] print seq[2,4] print seq[1::2] printing
foo ['baaz', 'mumble'] ['bar', 'quux'] 1>>> map(myList.__getitem__, (2,2,1,3)) ('baz', 'baz', 'bar', 'quux') You can also create your own List class which supports tuples as arguments to __getitem__ if you want to be able to do myList[(2,2,1,3)].
I just want to point out, even syntax of itemgetter looks really neat, but it's kinda slow when perform on large list.
import timeit from operator import itemgetter start=timeit.default_timer() for i in range(1000000): itemgetter(0,2,3)(myList) print ("Itemgetter took ", (timeit.default_timer()-start)) Itemgetter took 1.065209062149279
start=timeit.default_timer() for i in range(1000000): myList[0],myList[2],myList[3] print ("Multiple slice took ", (timeit.default_timer()-start)) Multiple slice took 0.6225321444745759
1Another possible solution:
sek=[] L=[1,2,3,4,5,6,7,8,9,0] for i in [2, 4, 7, 0, 3]: a=[L[i]] sek=sek+a print (sek) like often when you have a boolean numpy array like mask
[mylist[i] for i in np.arange(len(mask), dtype=int)[mask]]
A lambda that works for any sequence or np.array:
subseq = lambda myseq, mask : [myseq[i] for i in np.arange(len(mask), dtype=int)[mask]]
newseq = subseq(myseq, mask)