J'ai la liste Python suivante (peut également être un tuple):
myList = ['foo', 'bar', 'baz', 'quux']
je peux dire
>>> myList[0:3]
['foo', 'bar', 'baz']
>>> myList[::2]
['foo', 'baz']
>>> myList[1::2]
['bar', 'quux']
Comment sélectionner explicitement des éléments dont les index n'ont pas de modèles spécifiques? Par exemple, je veux sélectionner [0,2,3]
. Ou parmi une très grande liste de 1000 articles, je veux sélectionner [87, 342, 217, 998, 500]
. Y a-t-il une syntaxe Python qui fait cela? Quelque chose qui ressemble à:
>>> myBigList[87, 342, 217, 998, 500]
Réponses:
J'ai comparé les réponses avec python 2.5.2:
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] )
Notez que dans Python 3, le 1er a été changé pour être le même que le 4ème.
Une autre option serait de commencer par un
numpy.array
qui permet l'indexation via une liste ou unnumpy.array
:Le
tuple
ne fonctionne pas de la même manière que ce sont des tranches.la source
[myBigList[i] for i in [87, 342, 217, 998, 500]]
, mais j'aime bien cette approche.from operator import itemgetter
dans la partie initialisation depython -mtimeit
.myBigList[(87, 342, 217, 998, 500)]
ne fonctionne pas quandmyBigList
un python ordinairelist
? Quand j'essaye que je reçoisTypeError: list indices must be integers or slices, not tuple
. Ce serait tellement plus facile que de taper la compréhension - y a-t-il un problème de conception / mise en œuvre du langage?lists
qu'en Python n'acceptent que des entiers ou des tranches. La transmission d'un entier garantit qu'un seul élément est extrait d'une liste existante. Passer une tranche garantit qu'une partie de celle-ci est récupérée, mais passer un tuple revient à passer un type de données (tuple
) en tant qu'argument à un autre type de données (list
) qui est syntaxiquement incorrect.Et ça:
la source
operator
module!Ce n'est pas intégré, mais vous pouvez créer une sous-classe de liste qui prend les tuples comme "index" si vous le souhaitez:
impression
la source
Peut-être qu'une liste de compréhension est dans l'ordre:
Produit:
Est-ce ce que vous recherchez?
la source
Vous pouvez également créer votre propre
List
classe qui prend en charge les tuples comme arguments__getitem__
si vous voulez pouvoir le fairemyList[(2,2,1,3)]
.la source
operator
.len(myList)
overmyList.__len__()
.Je veux juste souligner que même la syntaxe d'itemgetter semble vraiment soignée, mais elle est un peu lente lorsqu'elle est exécutée sur une grande liste.
Itemgetter a pris 1.065209062149279
La tranche multiple a pris 0,6225321444745759
la source
myList = np.array(range(1000000))
sinon vous obtiendrez une erreur.Une autre solution possible:
la source
comme souvent quand vous avez un tableau numpy booléen comme
mask
[mylist[i] for i in np.arange(len(mask), dtype=int)[mask]]
Un lambda qui fonctionne pour n'importe quelle séquence ou np.array:
subseq = lambda myseq, mask : [myseq[i] for i in np.arange(len(mask), dtype=int)[mask]]
newseq = subseq(myseq, mask)
la source