web-dev-qa-db-fra.com

Python: filtrage des listes par index

Dans Python j'ai une liste d'éléments aList et une liste d'index myIndices. Existe-t-il un moyen de récupérer tout d'un coup ces éléments dans aList ayant comme indices les valeurs dans myIndices?

Exemple:

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

Je ne connais aucune méthode pour le faire. Mais vous pouvez utiliser un compréhension de la liste :

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

Utilisez certainement une compréhension de liste, mais voici une fonction qui le fait (il n'y a pas de méthodes de list qui le font). C'est cependant une mauvaise utilisation de itemgetter mais juste pour la connaissance j'ai posté ceci.

>>> 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')
10
jamylak

L'indexation par listes peut se faire en numpy. Convertissez votre liste de base en un tableau numpy, puis appliquez une autre liste en tant qu'index:

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

Si vous en avez besoin, reconvertissez-les en une liste à la fin:

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

Dans certains cas, cette solution peut être plus pratique que la compréhension de liste.

5
Marcin Wojnarski

Vous pouvez utiliser map

map(aList.__getitem__, myIndices)

ou operator.itemgetter

f = operator.itemgetter(*aList)
f(myIndices)
4
wenzul

Si vous n'avez pas besoin d'une liste avec un accès simultané à tous les éléments, mais souhaitez simplement utiliser tous les éléments de la sous-liste de manière itérative (ou les passer à quelque chose qui le fera), il est plus efficace d'utiliser une expression de générateur plutôt qu'une compréhension de liste :

(aList[i] for i in myIndices) 
3
watsonic

Je n'étais pas satisfait de ces solutions, j'ai donc créé une classe Flexlist qui étend simplement la classe list et permet une indexation flexible par entier, tranche ou liste d'index:

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

Ensuite, pour votre exemple, vous pouvez l'utiliser avec:

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

print(vals)  # ['a', 'd', 'e']
2
jedwards