Ich habe die folgende Python-Liste (kann auch ein Tuple sein):
myList = ['foo', 'bar', 'baz', 'quux']
Ich kann sagen
>>> myList[0:3]
['foo', 'bar', 'baz']
>>> myList[::2]
['foo', 'baz']
>>> myList[1::2]
['bar', 'quux']
Wie nehme ich explizit Artikel heraus, deren Indizes keine spezifischen Muster haben? Zum Beispiel möchte ich [0,2,3]
auswählen. Oder ich möchte aus einer sehr großen Liste von 1000 Artikeln [87, 342, 217, 998, 500]
auswählen. Gibt es eine Python-Syntax, die das tut? Etwas das aussieht:
>>> myBigList[87, 342, 217, 998, 500]
list( myBigList[i] for i in [87, 342, 217, 998, 500] )
Ich habe die Antworten mit Python 2.5.2 verglichen:
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] )
Beachten Sie, dass in Python 3 das 1st so geändert wurde, dass es mit dem 4th identisch ist.
Eine andere Möglichkeit wäre, mit einem numpy.array
zu beginnen, der die Indizierung über eine Liste oder einen numpy.array
ermöglicht:
>>> 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])
Die Variable Tuple
funktioniert nicht auf dieselbe Weise wie Slices.
Was ist mit diesem:
from operator import itemgetter
itemgetter(0,2,3)(myList)
('foo', 'baz', 'quux')
Es ist nicht integriert, aber Sie können eine Unterklasse einer Liste erstellen, die Tupel als "Indizes" verwendet, wenn Sie möchten:
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')
Sie können auch Ihre eigene List
-Klasse erstellen, die Tupel als Argumente für __getitem__
unterstützt, wenn Sie myList[(2,2,1,3)]
ausführen möchten.
Vielleicht ist ein Listenverständnis in Ordnung:
L = ['a', 'b', 'c', 'd', 'e', 'f']
print [ L[index] for index in [1,3,5] ]
Produziert:
['b', 'd', 'f']
Suchen Sie das?
Ich möchte nur darauf hinweisen, dass sogar die Syntax von itemgetter sehr ordentlich aussieht, aber es ist etwas langsam, wenn es auf einer großen Liste aufgeführt wird.
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 nahm 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))
Mehrere Slice nahmen 0,6225321444745759
wie oft, wenn Sie ein boolesches Numpy-Array wie mask
haben
[mylist[i] for i in np.arange(len(mask), dtype=int)[mask]]
Ein Lambda, das für jede Sequenz oder jedes np.array funktioniert:
subseq = lambda myseq, mask : [myseq[i] for i in np.arange(len(mask), dtype=int)[mask]]
newseq = subseq(myseq, mask)
Eine andere mögliche Lösung:
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)