明确地从Python列表或元组中select项目

我有以下的Python列表(也可以是一个元组):

myList = ['foo', 'bar', 'baz', 'quux'] 

我可以说

 >>> myList[0:3] ['foo', 'bar', 'baz'] >>> myList[::2] ['foo', 'baz'] >>> myList[1::2] ['bar', 'quux'] 

我如何明确地挑出指标没有特定模式的项目? 例如,我想select[0,2,3] 。 或者从一个非常大的1000个项目列表中,我想select[87, 342, 217, 998, 500] 。 有没有一些Python语法呢? 东西看起来像:

 >>> myBigList[87, 342, 217, 998, 500] 
 list( myBigList[i] for i in [87, 342, 217, 998, 500] ) 

我用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] )

请注意,在Python 3中,第1个被更改为与第4个相同。


另一种select是从numpy.array开始,它允许通过列表或numpy.arraybuild立索引:

 >>> 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]) 

tuple工作方式与那些片不一样。

那这个呢:

 from operator import itemgetter itemgetter(0,2,3)(myList) ('foo', 'baz', 'quux') 

它不是内置的,但是如果你愿意的话,你可以创build一个把元组作为“索引”的列表的子类:

 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] 

印花

 foo ['baaz', 'mumble'] ['bar', 'quux'] 
 >>> map(myList.__getitem__, (2,2,1,3)) ('baz', 'baz', 'bar', 'quux') 

如果你想能够做myList[(2,2,1,3)]你也可以创build自己的List类,它支持将元组作为__getitem__参数。

也许列表的理解是为了:

 L = ['a', 'b', 'c', 'd', 'e', 'f'] print [ L[index] for index in [1,3,5] ] 

生产:

 ['b', 'd', 'f'] 

那是你在找什么?

我只想指出,即使itemgetter的语法看起来非常整齐,但在大型列表中执行时还是比较慢。

 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花了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)) 

多片0.6225321444745759

另一个可能的解

 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)