it-swarm.com.de

Wählen Sie Elemente explizit aus einer Python-Liste oder einem Tupel aus

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]
86
Kit
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.

118
Dan D.

Was ist mit diesem:

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

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]

drucken

foo
['baaz', 'mumble']
['bar', 'quux']
9
Matt Anderson
>>> 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.

5
ninjagecko

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?

4
Dan Witkowski

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

1
Wendao Liu

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)

0
theo olsthoorn

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)
0
fdante