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]
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
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.
Method 2
What about this:
from operator import itemgetter
itemgetter(0,2,3)(myList)
('foo', 'baz', 'quux')
Method 3
Maybe 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?
Method 4
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']
Method 5
>>> 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)].
Method 6
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
Method 7
Another 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)
Method 8
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)
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0