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

3019
Eugene M 7 oct. 2008 à 05:39

27 réponses

Une variante de la réponse de FMc et user7177 donnera un dict qui peut retourner tous les indices 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 pour obtenir tous les indices pour une seule entrée. Il n'y a aucune garantie d'efficacité, bien que j'aie utilisé set (a) pour réduire le nombre d'appels du lambda.

12
bvanlew 28 mars 2014 à 09:11

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
Mathitis2Software 29 mai 2013 à 19:17

Une chose qui est vraiment utile pour apprendre Python est d'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.

881
davidavr 7 oct. 2008 à 13:19

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

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

Faisons notre fonction findindex

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

Sortie


[1, 3, 5, 7]

Facile

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

Production:

0
4
21
AkshayNevrekar 5 nov. 2018 à 12:18

Comme indiqué par @TerryA, de nombreuses réponses expliquent comment trouver un index.

more_itertools est une bibliothèque tierce avec des outils pour localiser plusieurs index dans un itérable.

Donné

import more_itertools as mit


iterable = ["foo", "bar", "baz", "ham", "foo", "bar", "baz"]

Code

Trouver 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. Installez via > pip install more_itertools.

1
pylang 25 sept. 2018 à 15:47

Pour ceux qui viennent d'une autre langue comme moi, peut-être qu'avec une simple boucle c'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 Que fait exactement l'énumération? . Cela m'a aidé à comprendre.

2
Peter Mortensen 4 juin 2018 à 20:55

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 s'il s'agit d'une liste vide. Cela fonctionne également avec les cordes.

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

Une fois collé dans une fenêtre python interactive:

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 autre année de développement tête baissée de python, je suis un peu gêné par ma réponse originale, donc pour remettre les pendules à l'heure, on peut certainement utiliser le code ci-dessus; cependant, la manière beaucoup plus idiomatique d'obtenir le même comportement serait d'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, une fois collé dans une fenêtre python interactive, 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 examiné cette question et toutes les réponses, je me rends compte que c'est exactement ce que FMc a suggéré dans son réponse précédente . Au moment où j'ai initialement répondu à cette question, je ne voyais pas cette réponse, car je ne la comprenais pas. J'espère que mon exemple un peu plus verbeux aidera à la compréhension.

Si la seule ligne de code ci-dessus n'a pas de sens pour vous, je vous recommande vivement de comprendre la liste de python de Google et de prendre quelques minutes pour vous familiariser. Ce n'est qu'une des nombreuses fonctionnalités puissantes qui rendent l'utilisation de Python très agréable pour développer du code.

15
MrWonderful 18 juil. 2018 à 10:01
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 tient compte si la chaîne n'est pas dans la liste aussi, si elle n'est pas dans la liste alors location = -1

5
AkshayNevrekar 13 févr. 2020 à 13:06

Recherche de l'index de l'élément x dans la liste L:

idx = L.index(x) if (x in L) else -1
7
Ketan 30 janv. 2019 à 17:36
a = ["foo","bar","baz",'bar','any','much']

indexes = [index for index in range(len(a)) if a[index] == 'bar']
75
savinson 31 oct. 2017 à 07:45

Pour obtenir tous les index:

indexes = [i for i,x in enumerate(xs) if x == 'foo']
164
Arkistarvh Kltzuonstev 30 juil. 2019 à 11:17

Vous pouvez simplement y 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 29 mai 2013 à 07:17

Donnons le nom lst à la liste que vous avez. On peut convertir la liste lst en numpy array. Et puis, utilisez numpy.where pour obtenir l'index de l'élément choisi dans la liste. Voici la manière dont vous allez l'implémenter.

import numpy as np

lst = ["foo", "bar", "baz"]  #lst: : 'list' data type
print np.where( np.array(lst) == 'bar')[0][0]

>>> 1
3
Siddharth Satpathy 28 nov. 2018 à 06:42

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')
22
Peter Mortensen 4 juin 2018 à 20:50

Vous devez définir une condition pour vérifier si l'élément que vous recherchez est dans la liste

if 'your_element' in mylist:
    print mylist.index('your_element')
else:
    print None
56
user3670684 26 mai 2014 à 04:26

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
Peter Mortensen 4 juin 2018 à 20:53

En utilisant le dictionnaire, où traiter d'abord la liste, 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
sahasrara62 18 mars 2019 à 09:32

Si vous voulez tous les index, 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.

38
Peter Mortensen 4 juin 2018 à 20:26

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() renvoie uniquement la première occurrence, tandis que enumerate() renvoie toutes les occurrences.

En tant que 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 que celle énumérée):

from itertools import izip as zip, count # izip for maximum efficiency
[i for i, j in zip(count(), ['foo', 'bar', 'baz']) if j == 'bar']

C'est plus efficace pour des listes plus grandes 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
530
Boris 21 janv. 2020 à 13:04

Un problème surviendra si l'élément n'est pas dans la liste. Cette fonction gère 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
81
tanzil 24 avril 2017 à 10:00

Étant donné que 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ù "meule de foin" est la liste en question et "aiguille" est l'élément à rechercher.

(Remarque: Ici, nous itérons en utilisant i pour obtenir les index, mais si nous devons plutôt nous concentrer sur les éléments, nous pouvons passer à j.)

5
Peter Mortensen 4 juin 2018 à 20:56

Cette solution n'est pas aussi puissante que les autres, mais si vous êtes débutant et ne connaissez que les boucles for, il est toujours possible de trouver le premier index d'un élément tout en évitant la ValueError:

def find_element(p,t):
    i = 0
    for e in p:
        if e == t:
            return i
        else:
            i +=1
    return -1
10
totallyhuman 12 nov. 2017 à 06:07

Si les performances sont préoccupantes:

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 cette opération une fois. Mais si vous devez accéder aux index des éléments un certain nombre de 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 en O (1) chaque fois que vous en avez besoin. il.

Si vous êtes sûr que les éléments de votre liste ne sont jamais répétés, 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 pouvez avoir des éléments en double et devez renvoyer tous leurs indices:

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 10 sept. 2018 à 18:51

Toutes les fonctions proposées ici reproduisent le comportement du langage inhérent mais obscurcissent 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 lui-même?

43
KeyWeeUsr 24 déc. 2016 à 14:24

Pour éviter ValueError, vous pouvez créer une fonction pour le faire, bien qu'une classe fonctionnerait également.

def findInList(List, item):
   try:
      return List.index(item)
   except ValueError:
      return -1

Le seul problème est qu'il pourrait provoquer un bug difficile à localiser; la même chose s'appliquerait à d'autres numéros.
Cependant, s'il retourne autre chose qu'un nombre, il sera probablement utilisé comme index de liste et générera inévitablement une erreur de toute façon.

À mon avis, en supposant que quelque chose a mal tourné si l'élément n'est pas trouvé, il est préférable d'utiliser un try - except, mais avec un message d'erreur personnalisé, et donc cela ne rendra pas le débogage plus difficile, la valeur de retour n'aura pas non plus d'importance:

# python 3.x

class itemNotFoundInListError(Exception): 
    pass

def findInList(List, item):
   try:
      return List.index(item)
   except ValueError:
      raise itemNotFoundInListError(f"List `{List}` does not contain `{item}.`")
1
Sapphire_Brick 29 oct. 2019 à 22:27

La méthode Python index() génère une erreur si l'élément est introuvable. Vous pouvez donc le rendre similaire à la fonction indexOf() de JavaScript qui renvoie -1 si l'élément n'est pas trouvé:

try:
    index = array.index('search_keyword')
except ValueError:
    index = -1
4
Arkistarvh Kltzuonstev 30 juil. 2019 à 11:19

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", quelle est la façon la plus propre d'obtenir son index (1) en Python?

Eh bien, bien sûr, il y a la méthode index, qui retourne 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 n'est pas dans la liste, vous obtiendrez un ValueError
  • si plusieurs valeurs figurent dans la liste, vous obtenez uniquement l'index du premier

Aucune valeur

Si la valeur peut être manquante, vous devez attraper le ValueError.

Vous pouvez le faire avec une définition réutilisable comme celle-ci:

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 devrez probablement vérifier si la valeur retournée is ou is not Aucune:

result = index(a_list, value)
if result is not None:
    do_something(result)

Plus d'une valeur dans la liste

Si vous pourriez avoir plus d'occurrences, vous n'obtiendrez pas d'informations complètes avec list.index:

>>> l.append('bar')
>>> l
['foo', 'bar', 'baz', 'bar']
>>> l.index('bar')              # nothing at index 3?
1

Vous pourriez énumérer dans une liste la compréhension des 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 une vérification booléenne du résultat, ou tout simplement ne rien faire si vous parcourez les résultats:

indexes = [index for index, v in enumerate(l) if v == 'boink']
for index in indexes:
    do_something(index)

Meilleure fusion des données avec les 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

Une vérification de comparaison renverra 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 souhaitez uniquement 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, passez-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 tout simplement pas aussi élégant, à mon avis - vous faites 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]

S'agit-il d'un problème XY?

Le problème XY pose des questions sur votre tentative de solution plutôt que sur votre problème réel.

Pourquoi pensez-vous que vous avez besoin de l'index donné un élément dans une liste?

Si vous connaissez déjà la valeur, pourquoi vous souciez-vous de son emplacement dans une liste?

Si la valeur n'est pas là, attraper le ValueError est plutôt bavard - et je préfère éviter cela.

Je suis généralement en train d'itérer sur la liste de toute façon, donc je garde généralement un pointeur vers toute information intéressante, obtenant l'index avec énumérer.

Si vous mungingez des données, vous devriez probablement utiliser des pandas - qui ont des outils beaucoup plus élégants que les solutions de contournement Python pures que j'ai montrées.

Je ne me souviens pas avoir eu besoin de list.index moi-même. Cependant, j'ai parcouru la bibliothèque standard de Python et je vois d'excellentes utilisations.

Il y a de très nombreuses utilisations dans idlelib, pour l'interface graphique et l'analyse de texte.

Le module keyword l'utilise pour trouver des marqueurs de commentaires dans le module pour régénérer automatiquement la liste de mots-clés qu'il contient via la 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)

Ce que ces usages semblent avoir en commun, c'est qu'ils semblent fonctionner sur des listes de tailles limitées (important en raison du temps de recherche O (n) pour list.index), et ils sont principalement utilisés dans l'analyse (et l'interface utilisateur dans le cas de ralenti).

Bien qu'il existe des cas d'utilisation pour cela, ils sont assez rares. Si vous vous trouvez à la recherche de 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.

31
Aaron Hall 2 sept. 2017 à 23:56
176918