2012-08-07 14 views
26

In Python habe ich eine Liste von Elementen aList und eine Liste von Indizes myIndices. Gibt es eine Möglichkeit, alle Elemente auf einmal in aList abzurufen, die als Indizes die Werte in myIndices haben?Python: Filtern von Listen nach Indizes

Beispiel:

>>> aList = ['a', 'b', 'c', 'd', 'e', 'f', 'g'] 
>>> myIndices = [0, 3, 4] 
>>> aList.A_FUNCTION(myIndices) 
['a', 'd', 'e'] 
+7

'[aList [i] für i in myIndices]' – Morwenn

+3

Wenn Sie nur über die Elemente iterieren wollen, schlage ich vor, stattdessen einen Generator Ausdruck zu verwenden : '(aList [i] für i in myIndices)' – hochl

Antwort

52

Ich kenne keine Methode, es zu tun. Aber Sie könnten ein list comprehension verwenden:

>>> [aList[i] for i in myIndices] 
9

Definitiv eine Liste Verständnis verwenden, aber hier ist eine Funktion, die es tut (es gibt keine Methoden von list, die dies tun). Dies ist jedoch eine schlechte Verwendung von itemgetter, aber nur um des Wissens willen habe ich dies gepostet.

>>> from operator import itemgetter 
>>> a_list = ['a', 'b', 'c', 'd', 'e', 'f', 'g'] 
>>> my_indices = [0, 3, 4] 
>>> itemgetter(*my_indices)(a_list) 
('a', 'd', 'e') 
+0

Ich glaube, das ist nicht der richtige Fall zu Verwende 'itemgetter'. –

+0

@BasicWolf Ja, du solltest es nicht benutzen, aber das OP hat nach einer Funktion gefragt, die das tun könnte, also habe ich einfach gezeigt, was es ist. Ich werde es deutlicher machen, dass Sie das nicht verwenden sollten. – jamylak

+0

Ich denke, dies wird auch durch die Begrenzung der maximalen Anzahl der Argumente begrenzt, die eine Funktion haben kann. – Paddy3118

5

Die Indexierung nach Listen kann in numpy erfolgen. Konvertieren Sie Ihre Basisliste in eine numpy Array und dann eine andere Liste als Index gilt:

>>> from numpy import array 
>>> array(aList)[myIndices] 
array(['a', 'd', 'e'], 
    dtype='|S1') 

Wenn Sie brauchen, konvertieren zurück in eine Liste am Ende:

>>> from numpy import array 
>>> a = array(aList)[myIndices] 
>>> list(a) 
['a', 'd', 'e'] 

In einigen Fällen kann diese Lösung bequemer sein als Listenverständnis.

1

war ich mit diesen Lösungen nicht glücklich, so habe ich eine Flexlist Klasse, die einfach die list-Klasse erweitert und ermöglicht eine flexible Indexierung durch integer, in Scheiben schneiden oder Index-Liste:

class Flexlist(list): 
    def __getitem__(self, keys): 
     if isinstance(keys, (int, slice)): return list.__getitem__(self, keys) 
     return [self[k] for k in keys] 

Dann wird für könnte

aList = Flexlist(['a', 'b', 'c', 'd', 'e', 'f', 'g']) 
myIndices = [0, 3, 4] 
vals = aList[myIndices] 

print(vals) # ['a', 'd', 'e'] 
+0

Das ist sehr nützlich. – mikeTronix

4

Sie map

map(aList.__getitem__, myIndices) 
verwenden: Ihr Beispiel könnten Sie es mit verwenden 10

oder operator.itemgetter

f = operator.itemgetter(*aList) 
f(myIndices) 
2

Wenn Sie keine Liste mit den gleichzeitigen Zugriff auf alle Elemente erfordern, sondern wollen nur iterativ alle Elemente in der Unterliste verwenden (oder sie zu etwas passieren, das wird), sein effizienten, einen Generator Ausdruck zu verwenden, anstatt Liste Verständnis:

(aList[i] for i in myIndices)