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']
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]
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')
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.
Vous pouvez utiliser map
map(aList.__getitem__, myIndices)
ou operator.itemgetter
f = operator.itemgetter(*aList)
f(myIndices)
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)
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']