Pour une liste ["foo", "bar", "baz"]
et un élément de la liste "bar"
, comment puis-je obtenir son index (1) en Python?
>>> ["foo", "bar", "baz"].index("bar")
1
Référence: Structures de données> Plus d'informations sur les listes
Notez que bien que ce soit peut-être la manière la plus propre de répondre à la question telle que posée , index
est un composant plutôt faible de la list
API, et je ne me souviens plus de la dernière fois où je l'ai utilisée avec colère. On m'a fait remarquer dans les commentaires que, comme cette réponse est fortement référencée, elle devrait être rendue plus complète. Quelques mises en garde concernant list.index
suivent. Cela vaut probablement la peine d’abord de jeter un coup d’œil à la docstring:
>>> print(list.index.__doc__)
L.index(value, [start, [stop]]) -> integer -- return first index of value.
Raises ValueError if the value is not present.
Un appel index
vérifie chaque élément de la liste dans l'ordre, jusqu'à ce qu'il trouve une correspondance. Si votre liste est longue et que vous ne savez pas approximativement où elle se trouve, cette recherche pourrait devenir un goulot d'étranglement. Dans ce cas, vous devriez envisager une structure de données différente. Notez que si vous savez approximativement où trouver la correspondance, vous pouvez donner un indice à index
. Par exemple, dans cet extrait, l.index(999_999, 999_990, 1_000_000)
est environ cinq ordres de magnitude plus rapide que straight l.index(999_999)
, car le premier ne doit rechercher que 10 entrées, tandis que le second recherche un million:
>>> import timeit
>>> timeit.timeit('l.index(999_999)', setup='l = list(range(0, 1_000_000))', number=1000)
9.356267921015387
>>> timeit.timeit('l.index(999_999, 999_990, 1_000_000)', setup='l = list(range(0, 1_000_000))', number=1000)
0.0004404920036904514
Un appel à index
parcourt la liste dans l’ordre jusqu’à ce qu’il trouve une correspondance et s’arrête là. Si vous prévoyez d’avoir besoin d’indices de plus correspond, vous devez utiliser une compréhension de liste ou une expression génératrice.
>>> [1, 1].index(1)
0
>>> [i for i, e in enumerate([1, 2, 1]) if e == 1]
[0, 2]
>>> g = (i for i, e in enumerate([1, 2, 1]) if e == 1)
>>> next(g)
0
>>> next(g)
2
La plupart des endroits où j’aurais utilisé jadis index
, j’utilise maintenant une compréhension de liste ou une expression génératrice car ils sont plus généralisables. Donc, si vous envisagez d'atteindre index
, jetez un coup d'œil à ces excellentes fonctionnalités de python.
Un appel à index
aboutit à un ValueError
si l'élément n'est pas présent.
>>> [1, 1].index(2)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: 2 is not in list
Si l'élément ne figure peut-être pas dans la liste, vous devez soit:
item in my_list
(approche propre et lisible), ouindex
dans un bloc try/except
qui capture ValueError
(probablement plus rapidement, du moins lorsque la liste à rechercher est longue et que l'élément est généralement présent.)Une chose qui est vraiment utile pour apprendre Python consiste à utiliser la fonction d'aide interactive:
>>> help(["foo", "bar", "baz"])
Help on list object:
class list(object)
...
|
| index(...)
| L.index(value, [start, [stop]]) -> integer -- return first index of value
|
ce qui vous mènera souvent à la méthode que vous recherchez.
La majorité des réponses expliquent comment trouver un seul index , mais leurs méthodes ne renvoient pas plusieurs index si l'élément figure plusieurs fois dans la liste. Utilisez enumerate()
:
for i, j in enumerate(['foo', 'bar', 'baz']):
if j == 'bar':
print(i)
La fonction index()
ne renvoie que la première occurrence, alors que enumerate()
renvoie toutes les occurrences.
En compréhension de liste:
[i for i, j in enumerate(['foo', 'bar', 'baz']) if j == 'bar']
Voici également une autre petite solution avec itertools.count()
(qui est à peu près la même approche qu'énumérer):
from itertools import izip as Zip, count # izip for maximum efficiency
[i for i, j in Zip(count(), ['foo', 'bar', 'baz']) if j == 'bar']
Ceci est plus efficace pour les grandes listes que d'utiliser enumerate()
:
$ python -m timeit -s "from itertools import izip as Zip, count" "[i for i, j in Zip(count(), ['foo', 'bar', 'baz']*500) if j == 'bar']"
10000 loops, best of 3: 174 usec per loop
$ python -m timeit "[i for i, j in enumerate(['foo', 'bar', 'baz']*500) if j == 'bar']"
10000 loops, best of 3: 196 usec per loop
Pour obtenir tous les index:
indexes = [i for i,x in enumerate(xs) if x == 'foo']
index()
renvoie le premier index de valeur!
| indice(...)
| L.index (valeur, [début, [arrêt]]) -> entier - retourne le premier index de la valeur
def all_indices(value, qlist):
indices = []
idx = -1
while True:
try:
idx = qlist.index(value, idx+1)
indices.append(idx)
except ValueError:
break
return indices
all_indices("foo", ["foo","bar","baz","foo"])
Un problème se posera si l'élément n'est pas dans la liste. Cette fonction traite le problème:
# if element is found it returns index of element else returns None
def find_element_in_list(element, list_element):
try:
index_element = list_element.index(element)
return index_element
except ValueError:
return None
a = ["foo","bar","baz",'bar','any','much']
indexes = [index for index in range(len(a)) if a[index] == 'bar']
Vous devez définir une condition pour vérifier si l'élément que vous recherchez est bien dans la liste.
if 'your_element' in mylist:
print mylist.index('your_element')
else:
print None
Toutes les fonctions proposées ici reproduisent le comportement inhérent au langage mais masquent ce qui se passe.
[i for i in range(len(mylist)) if mylist[i]==myterm] # get the indices
[each for each in mylist if each==myterm] # get the items
mylist.index(myterm) if myterm in mylist else None # get the first index and fail quietly
Pourquoi écrire une fonction avec gestion des exceptions si le langage fournit les méthodes pour faire ce que vous voulez?
Si vous voulez tous les index, alors vous pouvez utiliser NumPy :
import numpy as np
array = [1, 2, 1, 3, 4, 5, 1]
item = 1
np_array = np.array(array)
item_index = np.where(np_array==item)
print item_index
# Out: (array([0, 2, 6], dtype=int64),)
C'est une solution claire et lisible.
Trouver l'index d'un élément à partir d'une liste le contenant en Python
Pour une liste
["foo", "bar", "baz"]
et un élément de la liste"bar"
, quel est le moyen le plus propre d’obtenir son index (1) en Python?
Eh bien, bien sûr, il y a la méthode index, qui renvoie l'index de la première occurrence:
>>> l = ["foo", "bar", "baz"]
>>> l.index('bar')
1
Il y a quelques problèmes avec cette méthode:
ValueError
Si la valeur peut être manquante, vous devez attraper le ValueError
.
Vous pouvez le faire avec une définition réutilisable comme ceci:
def index(a_list, value):
try:
return a_list.index(value)
except ValueError:
return None
Et utilisez-le comme ceci:
>>> print(index(l, 'quux'))
None
>>> print(index(l, 'bar'))
1
Et l'inconvénient est que vous aurez probablement un contrôle pour savoir si la valeur retournée is
ou is not
None:
result = index(a_list, value)
if result is not None:
do_something(result)
Si vous pouviez avoir plus d'occurrences, vous obtiendrez des informations complètes avec list.index
et non :
>>> l.append('bar')
>>> l
['foo', 'bar', 'baz', 'bar']
>>> l.index('bar') # nothing at index 3?
1
Vous pouvez énumérer dans une liste de compréhension les index:
>>> [index for index, v in enumerate(l) if v == 'bar']
[1, 3]
>>> [index for index, v in enumerate(l) if v == 'boink']
[]
Si vous n'avez aucune occurrence, vous pouvez vérifier cela avec la vérification booléenne du résultat, ou tout simplement ne rien faire si vous passez en boucle sur les résultats:
indexes = [index for index, v in enumerate(l) if v == 'boink']
for index in indexes:
do_something(index)
Si vous avez des pandas, vous pouvez facilement obtenir ces informations avec un objet Series:
>>> import pandas as pd
>>> series = pd.Series(l)
>>> series
0 foo
1 bar
2 baz
3 bar
dtype: object
Un contrôle de comparaison retournera une série de booléens:
>>> series == 'bar'
0 False
1 True
2 False
3 True
dtype: bool
Passez cette série de booléens à la série via la notation en indice, et vous obtenez uniquement les membres correspondants:
>>> series[series == 'bar']
1 bar
3 bar
dtype: object
Si vous ne voulez que les index, l'attribut index renvoie une série d'entiers:
>>> series[series == 'bar'].index
Int64Index([1, 3], dtype='int64')
Et si vous les voulez dans une liste ou un tuple, transmettez-les simplement au constructeur:
>>> list(series[series == 'bar'].index)
[1, 3]
Oui, vous pouvez également utiliser une compréhension de liste avec énumération, mais ce n’est pas aussi élégant, à mon avis: vous effectuez des tests d’égalité en Python, au lieu de laisser le code intégré écrit en C le gérer:
>>> [i for i, value in enumerate(l) if value == 'bar']
[1, 3]
Le problème XY concerne votre tentative de solution plutôt que votre problème actuel.
Pourquoi pensez-vous que vous avez besoin de l'index étant donné un élément dans une liste?
Si vous connaissez déjà la valeur, pourquoi vous souciez-vous de la trouver dans une liste?
Si la valeur est absente, intercepter la ValueError
est plutôt verbeux - et je préfère éviter cela.
Quoi qu’il en soit, j’ai l'habitude de parcourir la liste de toute façon, donc je garde habituellement un pointeur sur toute information intéressante, pour obtenir le index avec énumération.
Si vous collectez des données, vous devriez probablement utiliser pandas - qui propose des outils beaucoup plus élégants que les solutions de contournement Python pures que j'ai présentées.
Je ne me rappelle pas avoir eu besoin de list.index
, moi-même. Cependant, j’ai parcouru la bibliothèque standard Python et j’y trouve d’excellentes utilisations.
Il y a de très nombreuses utilisations pour cela dans idlelib
, pour l'analyse graphique et le texte.
Le module keyword
l'utilise pour rechercher des marqueurs de commentaire dans le module afin de régénérer automatiquement la liste de mots-clés qu'il contient via une métaprogrammation.
Dans Lib/mailbox.py, il semble l'utiliser comme un mappage ordonné:
key_list[key_list.index(old)] = new
et
del key_list[key_list.index(key)]
Dans Lib/http/cookiejar.py, semble être utilisé pour obtenir le mois prochain:
mon = MONTHS_LOWER.index(mon.lower())+1
Dans Lib/tarfile.py similaire à distutils pour obtenir une tranche jusqu’à un élément:
members = members[:members.index(tarinfo)]
Dans Lib/pickletools.py:
numtopop = before.index(markobject)
Le point commun entre ces usages est qu’ils semblent opérer sur des listes de tailles limitées (important en raison de O(n) temps de recherche pour list.index
), et ils sont principalement utilisés dans l'analyse syntaxique (et l'interface utilisateur dans le cas de veille).
Bien qu'il existe des cas d'utilisation, ils sont assez rares. Si vous cherchez cette réponse, demandez-vous si ce que vous faites est l'utilisation la plus directe des outils fournis par la langue pour votre cas d'utilisation.
Tous les index avec la fonction Zip
:
get_indexes = lambda x, xs: [i for (y, i) in Zip(xs, range(len(xs))) if x == y]
print get_indexes(2, [1, 2, 3, 4, 5, 6, 3, 2, 3, 2])
print get_indexes('f', 'xsfhhttytffsafweef')
Enumerate (alist) vous permet de 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 comme arguments l'argument et la liste 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"))
sortie
[1, 3, 5, 7]
for n, i in enumerate([1, 2, 3, 4, 1]):
if i == 1:
print(n)
Sortie:
0
4
Vous pouvez simplement aller avec
a = [['hand', 'head'], ['phone', 'wallet'], ['lost', 'stock']]
b = ['phone', 'lost']
res = [[x[0] for x in a].index(y) for y in b]
Une autre option
>>> a = ['red', 'blue', 'green', 'red']
>>> b = 'red'
>>> offset = 0;
>>> indices = list()
>>> for i in range(a.count(b)):
... indices.append(a.index(b,offset))
... offset = indices[-1]+1
...
>>> indices
[0, 3]
>>>
... comme confirmer l'existence de l'élément avant d'obtenir l'index. La bonne chose à propos de cette approche est que la fonction retourne toujours une liste d’index - même si c’est une liste vide. Cela fonctionne aussi avec les chaînes.
def indices(l, val):
"""Always returns a list containing the indices of val in the_list"""
retval = []
last = 0
while val in l[last:]:
i = l[last:].index(val)
retval.append(last + i)
last += i + 1
return retval
l = ['bar','foo','bar','baz','bar','bar']
q = 'bar'
print indices(l,q)
print indices(l,'bat')
print indices('abcdaababb','a')
Lorsque collé dans une fenêtre interactive python:
Python 2.7.6 (v2.7.6:3a1db0d2747e, Nov 10 2013, 00:42:54)
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> def indices(the_list, val):
... """Always returns a list containing the indices of val in the_list"""
... retval = []
... last = 0
... while val in the_list[last:]:
... i = the_list[last:].index(val)
... retval.append(last + i)
... last += i + 1
... return retval
...
>>> l = ['bar','foo','bar','baz','bar','bar']
>>> q = 'bar'
>>> print indices(l,q)
[0, 2, 4, 5]
>>> print indices(l,'bat')
[]
>>> print indices('abcdaababb','a')
[0, 4, 5, 7]
>>>
Après une nouvelle année de développement python en tête-à-tête, je suis un peu gêné par ma réponse originale. Par conséquent, pour mettre les choses au clair, on peut certainement utiliser le code ci-dessus; Cependant, la manière la plus idiomatique d'obtenir le même comportement consisterait à utiliser la compréhension de liste, avec la fonction enumerate ().
Quelque chose comme ça:
def indices(l, val):
"""Always returns a list containing the indices of val in the_list"""
return [index for index, value in enumerate(l) if value == val]
l = ['bar','foo','bar','baz','bar','bar']
q = 'bar'
print indices(l,q)
print indices(l,'bat')
print indices('abcdaababb','a')
Ce qui, lorsqu'il est collé dans une fenêtre interactive python, donne:
Python 2.7.14 |Anaconda, Inc.| (default, Dec 7 2017, 11:07:58)
[GCC 4.2.1 Compatible Clang 4.0.1 (tags/RELEASE_401/final)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> def indices(l, val):
... """Always returns a list containing the indices of val in the_list"""
... return [index for index, value in enumerate(l) if value == val]
...
>>> l = ['bar','foo','bar','baz','bar','bar']
>>> q = 'bar'
>>> print indices(l,q)
[0, 2, 4, 5]
>>> print indices(l,'bat')
[]
>>> print indices('abcdaababb','a')
[0, 4, 5, 7]
>>>
Et maintenant, après avoir passé en revue cette question et toutes les réponses, je me rends compte que c’est exactement ce que FMc suggéré dans son réponse précédente . À l'époque où j'avais initialement répondu à cette question, je n'avais même pas vu cette réponse, car je ne l'avais pas comprise. J'espère que mon exemple un peu plus détaillé aidera à la compréhension.
Si la seule ligne de code ci-dessus n'a toujours aucun sens , je vous recommande vivement Google de "comprendre la liste python" et de prendre quelques minutes pour le faire. Familiarisez-vous. C'est l'une des nombreuses fonctionnalités puissantes qui rendent l'utilisation de Python pour le développement du code agréable.
Une variante de la réponse de FMc et de l'utilisateur7177 donnera un dict qui peut renvoyer tous les index pour n'importe quelle entrée:
>>> a = ['foo','bar','baz','bar','any', 'foo', 'much']
>>> l = dict(Zip(set(a), map(lambda y: [i for i,z in enumerate(a) if z is y ], set(a))))
>>> l['foo']
[0, 5]
>>> l ['much']
[6]
>>> l
{'baz': [2], 'foo': [0, 5], 'bar': [1, 3], 'any': [4], 'much': [6]}
>>>
Vous pouvez également l'utiliser comme une ligne unique pour obtenir tous les indices d'une seule entrée. Il n'y a aucune garantie d'efficacité, bien que j'aie utilisé set (a) pour réduire le nombre de fois que le lambda est appelé.
Cette solution n'est pas aussi puissante que les autres, mais si vous êtes débutant et que vous ne connaissez que for
loops, il est toujours possible de trouver le premier index d'un élément tout en évitant ValueError:
def find_element(p,t):
i = 0
for e in p:
if e == t:
return i
else:
i +=1
return -1
Indice de recherche de l'élément x dans la liste L:
idx = L.index(x) if (x in L) else -1
Comme les listes Python sont basées sur zéro, nous pouvons utiliser la fonction intégrée Zip comme suit:
>>> [i for i,j in Zip(range(len(haystack)), haystack) if j == 'needle' ]
où "botte de foin" est la liste en question et "aiguille" est l'élément à rechercher.
(Remarque: ici, nous effectuons une itération en utilisant i pour obtenir les index, mais si nous devons plutôt nous concentrer sur les éléments, nous pouvons passer à j.)
name ="bar"
list = [["foo", 1], ["bar", 2], ["baz", 3]]
new_list=[]
for item in list:
new_list.append(item[0])
print(new_list)
try:
location= new_list.index(name)
except:
location=-1
print (location)
Cela explique si la chaîne n'est pas dans la liste aussi, si elle ne fait pas partie de la liste alors location = -1
La méthode Python index()
renvoie une erreur si l'élément n'a pas été trouvé. Vous pouvez donc le rendre similaire à la fonction indexOf()
de JavaScript qui renvoie -1
si l'élément n'a pas été trouvé:
try:
index = array.index('search_keyword')
except ValueError:
index = -1
Si la liste ne contient pas d’éléments répétés, vous avez deux possibilités pour vérifier l’index.
eg: li=[10,20,30] # here need to get index of 20 means
li.index(20) # will work properly because 20 is not repeated
si sa répétition signifie qu'il ne vous donnera que le premier index
Si vous devez obtenir tous les index où l'élément est présent, cela signifie
eg: li=[10,20,30,20,40, 50, 10] # here need to get index of 20 means its have 2 index (1,3)
pour obtenir ce que vous devez faire comme
li=[10,20,30,20,40, 50, 10]
[i for i, e in enumerate(li) if e == 20]
alors vous obtiendrez une liste d'index comme o/p comme [1,3]
Il y a une réponse plus fonctionnelle à cela.
list(filter(lambda x: x[1]=="bar",enumerate(["foo", "bar", "baz", "bar", "baz", "bar", "a", "b", "c"])))
Forme plus générique:
def get_index_of(lst, element):
return list(map(lambda x: x[0],\
(list(filter(lambda x: x[1]==element, enumerate(lst))))))
Donnons le nom lst
à la liste que vous avez. On peut convertir la liste lst
en un numpy array
. Et, ensuite, utilisez numpy.where pour obtenir l'index de l'élément choisi dans la liste. Voici comment vous allez le mettre en œuvre.
import numpy as np
lst = ["foo", "bar", "baz"] #lst: : 'list' data type
print np.where( np.array(lst) == 'bar')[0][0]
>>> 1
Pour ceux qui viennent d'une autre langue comme moi, peut-être qu'avec une simple boucle, il est plus facile à comprendre et à utiliser:
mylist = ["foo", "bar", "baz", "bar"]
newlist = enumerate(mylist)
for index, item in newlist:
if item == "bar":
print(index, item)
Je suis reconnaissant pour Alors qu'est-ce que énumérer fait exactement?. Cela m'a aidé à comprendre.
Il est mentionné dans de nombreuses réponses que la méthode intégrée de la méthode list.index(item)
est un algorithme O(n). C'est bien si vous devez effectuer ceci une fois. Mais si vous devez accéder aux index d'éléments plusieurs fois, il est plus logique de créer d'abord un dictionnaire (O (n)) de paires élément-index, puis d'accéder à l'index à partir de O(1). chaque fois que vous en avez besoin.
Si vous êtes sûr que les éléments de votre liste ne se répètent jamais, vous pouvez facilement:
myList = ["foo", "bar", "baz"]
# Create the dictionary
myDict = dict((e,i) for i,e in enumerate(myList))
# Lookup
myDict["bar"] # Returns 1
# myDict.get("blah") if you don't want an error to be raised if element not found.
Si vous avez des éléments en double et que vous devez renvoyer tous leurs index:
from collections import defaultdict as dd
myList = ["foo", "bar", "bar", "baz", "foo"]
# Create the dictionary
myDict = dd(list)
for i,e in enumerate(myList):
myDict[e].append(i)
# Lookup
myDict["foo"] # Returns [0, 4]
Comme indiqué par @TerryA, de nombreuses réponses expliquent comment trouver un index.
more_itertools
est une bibliothèque tierce avec des outils permettant de localiser plusieurs index au sein d'un itérable.
Étant donné
_import more_itertools as mit
iterable = ["foo", "bar", "baz", "ham", "foo", "bar", "baz"]
_
Code
Trouvez des indices d'observations multiples:
_list(mit.locate(iterable, lambda x: x == "bar"))
# [1, 5]
_
Testez plusieurs éléments:
_list(mit.locate(iterable, lambda x: x in {"bar", "ham"}))
# [1, 3, 5]
_
Voir aussi plus d'options avec more_itertools.locate
. Installer via > pip install more_itertools
.
en utilisant un dictionnaire, où traiter la liste en premier, puis y ajouter l'index
from collections import defaultdict
index_dict = defaultdict(list)
Word_list = ['foo','bar','baz','bar','any', 'foo', 'much']
for Word_index in range(len(Word_list)) :
index_dict[Word_list[Word_index]].append(Word_index)
Word_index_to_find = 'foo'
print(index_dict[Word_index_to_find])
# output : [0, 5]