index()donnera juste la première occurrence d'un élément dans une liste. Existe-t-il une astuce intéressante qui renvoie tous les indices d'une liste?
index()donnera juste la première occurrence d'un élément dans une liste. Existe-t-il une astuce intéressante qui renvoie tous les indices d'une liste?
Réponses:
Vous pouvez utiliser une liste de compréhension:
indices = [i for i, x in enumerate(my_list) if x == "whatever"]
enumerateà 2.3. Alors oui, si votre Python est ancien, utilisez filter().
print([i for i, x in enumerate([[1,1],[0,1]]) if x == 1])renvoie []au lieu de [[0, 1], [0, 0], [1, 1]].
(a == 1).nonzero()pour un tableau NumPy a.
Bien que ce ne soit pas une solution pour les listes directement, numpybrille vraiment pour ce genre de chose:
import numpy as np
values = np.array([1,2,3,1,2,4,5,6,3,2,1])
searchval = 3
ii = np.where(values == searchval)[0]
Retour:
ii ==>array([2, 8])
Cela peut être beaucoup plus rapide pour les listes (tableaux) avec un grand nombre d'éléments par rapport à certaines des autres solutions.
[0]est nécessaire car whereretourne un tuple(array([2, 8], dtype=int64),)
all_id_resp_addressne devrait tout d'abord np.arraypas l' être list.
listet str, évidemment, vous êtes passé Falseà np.where. Lorsque vous comparez np.arrayavec smth. vous obtenez un tableau de valeurs booléennes. Trouve ensuite les np.wherepositions de toutes les Truevaleurs de ce tableau.
Une solution utilisant list.index:
def indices(lst, element):
result = []
offset = -1
while True:
try:
offset = lst.index(element, offset+1)
except ValueError:
return result
result.append(offset)
C'est beaucoup plus rapide que la compréhension de liste avec enumerate, pour les grandes listes. Il est également beaucoup plus lent que la numpysolution si vous disposez déjà de la matrice, sinon le coût de conversion l'emporte sur le gain de vitesse (testé sur des listes entières avec 100, 1000 et 10000 éléments).
REMARQUE: une note de prudence basée sur le commentaire de Chris_Rands: cette solution est plus rapide que la compréhension de la liste si les résultats sont suffisamment clairsemés, mais si la liste contient de nombreuses instances de l'élément recherché (plus de ~ 15% de la liste , sur un test avec une liste de 1000 entiers), la compréhension de la liste est plus rapide.
timeit.timeitavec des listes générées aléatoirement. C'est un point important cependant, et je suppose que c'est peut-être pourquoi vous posez la question. À l'époque, cela ne m'est pas venu à l'esprit, mais les gains de vitesse ne sont vrais que si les résultats sont suffisamment clairsemés. Je viens de tester avec une liste pleine d'éléments à rechercher, et c'est beaucoup plus lent que la compréhension de la liste.
more_itertools.locate recherche des indices pour tous les éléments qui remplissent une condition.
from more_itertools import locate
list(locate([0, 1, 1, 0, 1, 0, 0]))
# [1, 2, 4]
list(locate(['a', 'b', 'c', 'b'], lambda x: x == 'b'))
# [1, 3]
more_itertoolsest une bibliothèque tierce > pip install more_itertools.
conda installsoit devenue très instable récemment)
Une autre solution (désolé si les doublons) pour toutes les occurrences:
values = [1,2,3,1,2,4,5,6,3,2,1]
map(lambda val: (val, [i for i in xrange(len(values)) if values[i] == val]), values)
Ou utilisez range(python 3):
l=[i for i in range(len(lst)) if lst[i]=='something...']
Pour (python 2):
l=[i for i in xrange(len(lst)) if lst[i]=='something...']
Et puis (dans les deux cas):
print(l)
Est comme prévu.
Utilisation de filter () en python2.
>>> q = ['Yeehaw', 'Yeehaw', 'Googol', 'B9', 'Googol', 'NSM', 'B9', 'NSM', 'Dont Ask', 'Googol']
>>> filter(lambda i: q[i]=="Googol", range(len(q)))
[2, 4, 9]
Vous pouvez créer un dicton par défaut
from collections import defaultdict
d1 = defaultdict(int) # defaults to 0 values for keys
unq = set(lst1) # lst1 = [1, 2, 2, 3, 4, 1, 2, 7]
for each in unq:
d1[each] = lst1.count(each)
else:
print(d1)
Avec enumerate (alist), vous pouvez stocker le premier élément (n) qui est l'index de la liste lorsque l'élément x est égal à ce que vous recherchez.
>>> alist = ['foo', 'spam', 'egg', 'foo']
>>> foo_indexes = [n for n,x in enumerate(alist) if x=='foo']
>>> foo_indexes
[0, 3]
>>>
Cette fonction prend l'élément et la liste comme arguments et renvoie la position de l'élément dans la liste, comme nous l'avons vu précédemment.
def indexlist(item2find, list_or_string):
"Returns all indexes of an item in a list or a string"
return [n for n,item in enumerate(list_or_string) if item==item2find]
print(indexlist("1", "010101010"))
Production
[1, 3, 5, 7]
for n, i in enumerate([1, 2, 3, 4, 1]):
if i == 1:
print(n)
Production:
0
4
for-loop:enumerate et une compréhension de liste sont plus efficaces et pythoniques, cependant, cette réponse s'adresse aux étudiants qui peuvent ne pas être autorisés à utiliser certaines de ces fonctions intégrées .indicesfor i in range(len(x)):, qui itère essentiellement à travers une liste d'emplacements d'index[0, 1, 2, 3, ..., len(x)-1]ioù, oùx[i] correspond à value, àindices
def get_indices(x: list, value: int) -> list:
indices = list()
for i in range(len(x)):
if x[i] == value:
indices.append(i)
return indices
n = [1, 2, 3, -50, -60, 0, 6, 9, -60, -60]
print(get_indices(n, -60))
>>> [4, 8, 9]
get_indices,, sont implémentées avec des indications de type . Dans ce cas, la liste n, est un tas deint s, donc nous recherchons value, également défini comme un int.while-loop et .index:.index, utilisez try-exceptpour la gestion des erreurs car un ValueErrorse produira s'il valuene figure pas dans la liste.def get_indices(x: list, value: int) -> list:
indices = list()
i = 0
while True:
try:
# find an occurrence of value and update i to that index
i = x.index(value, i)
# add i to the list
indices.append(i)
# advance i by 1
i += 1
except ValueError as e:
break
return indices
print(get_indices(n, -60))
>>> [4, 8, 9]
get_indeicesest un peu plus rapide (~ 15%) que la compréhension de liste normale. J'essaie de comprendre.
Si vous utilisez Python 2, vous pouvez obtenir les mêmes fonctionnalités avec ceci:
f = lambda my_list, value:filter(lambda x: my_list[x] == value, range(len(my_list)))
Où se my_listtrouve la liste dont vous souhaitez obtenir les index et valuela valeur recherchée. Usage:
f(some_list, some_element)
Si vous devez rechercher toutes les positions des éléments entre certains indices , vous pouvez les indiquer:
[i for i,x in enumerate([1,2,3,2]) if x==2 & 2<= i <=3] # -> [3]