web-dev-qa-db-fra.com

Trouver l'index d'un élément à l'aide d'une liste le contenant dans Python

Pour une liste ["foo", "bar", "baz"] et un élément de la liste "bar", comment puis-je obtenir son index (1) en Python?

2785
Eugene M
>>> ["foo", "bar", "baz"].index("bar")
1

Référence: Structures de données> Plus d'informations sur les listes

Les mises en garde suivent

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.

Temps complexe en longueur dans la liste

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

Renvoie uniquement l'index de la première correspondance à son argument

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.

Lance si élément non présent dans la liste

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:

  1. Vérifiez-le d'abord avec item in my_list (approche propre et lisible), ou
  2. Enveloppez l'appel index 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.)
3983
Alex Coventry

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.

851
davidavr

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
506
TerryA

Pour obtenir tous les index:

indexes = [i for i,x in enumerate(xs) if x == 'foo']
149
FMc

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"])
123
HongboZhu

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
75
tanzil
a = ["foo","bar","baz",'bar','any','much']

indexes = [index for index in range(len(a)) if a[index] == 'bar']
69
savinson

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
50
user3670684

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?

40
Graham Giller

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.

35
rbrisuda

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:

  • si la valeur ne figure pas dans la liste, vous obtenez un ValueError
  • si plus d'une valeur est dans la liste, vous n'obtenez que l'index pour le premier

Pas de valeurs

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)

Plus d'une valeur dans la liste

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)

De meilleures données se mêlant aux pandas

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]

Est-ce un problème XY ?

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.

27
Aaron Hall

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

Obtenir toutes les occurrences et la position d'un ou plusieurs éléments (identiques) dans une liste

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]
>>>

Faisons notre fonction findindex

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]

Facile

for n, i in enumerate([1, 2, 3, 4, 1]):
    if i == 1:
        print(n)

Sortie:

0
4
19
Giovanni Python

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]
16
kiriloff

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]
>>> 
16

Et maintenant pour quelque chose de complètement différent...

... 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]
>>> 

Mise à jour

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.

15
MrWonderful

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é.

12
bvanlew

Cette solution n'est pas aussi puissante que les autres, mais si vous êtes débutant et que vous ne connaissez que forloops, 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
10
dylankb

Indice de recherche de l'élément x dans la liste L:

idx = L.index(x) if (x in L) else -1
6
Ketan

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.)

5
jihed gasmi
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

5
Coder123

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
4
Hamed Baatour

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]

3
abhi krishnan

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))))))
3
Ankit Gupta

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
2
Siddharth Satpathy

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.

1
mpoletto

Si la performance est une préoccupation:

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]
1
FatihAkici

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 .

1
pylang

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]
0
prashant rana