Recherche de l'index d'un élément dans une liste


3187

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


6
Renvoyez-vous: [1] L'indice le plus bas en cas de plusieurs instances de "bar", [2] Tous les indices de "bar"?
Ṃųỻịgǻňạcểơửṩ

4
a) Est-il garanti que l'élément est dans la liste, ou bien comment traiter le cas d'erreur? (return None / raise ValueError) b) Les entrées de liste sont-elles garanties uniques et devons-nous renvoyer le premier index d'une correspondance ou tous les index?
smci

Affichez les réponses avec l'intégration numpy, les tableaux numpy sont beaucoup plus efficaces que les listes Python. Si la liste est courte, cela ne pose aucun problème d'en faire une copie à partir d'une liste Python, sinon, vous devriez peut-être envisager de stocker les éléments dans le tableau numpy en premier lieu.
Athanassios

Réponses:


4492
>>> ["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 le moyen le plus propre de répondre à la question posée , indexc'est un composant plutôt faible de l' listAPI, et je ne me souviens pas de la dernière fois que je l'ai utilisé avec colère. On m'a fait remarquer dans les commentaires que, parce que cette réponse est fortement référencée, elle devrait être rendue plus complète. Quelques mises en garde à propos de list.indexsuivre. Il vaut probablement la peine de jeter un coup d'œil à la documentation:

list.index(x[, start[, end]])

Retourne un index de base zéro dans la liste du premier élément dont la valeur est égale à x . Déclenche un ValueErrors'il n'y en a pas.

Les arguments facultatifs début et fin sont interprétés comme dans la notation de tranche et sont utilisés pour limiter la recherche à une sous-séquence particulière de la liste. L'index renvoyé est calculé par rapport au début de la séquence complète plutôt que par l'argument de début.

Complexité temporelle linéaire en longueur de liste

Un indexappel 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 à peu près où dans la liste elle se produit, cette recherche pourrait devenir un goulot d'étranglement. Dans ce cas, vous devez envisager une structure de données différente. Notez que si vous savez à peu près où trouver la correspondance, vous pouvez donner indexun indice. Par exemple, dans cet extrait, l.index(999_999, 999_990, 1_000_000)est environ cinq ordres de grandeur plus rapide que droit l.index(999_999), car le premier n'a qu'à rechercher 10 entrées, tandis que le second en 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 à indexrecherche dans la liste dans l'ordre jusqu'à ce qu'il trouve une correspondance et s'arrête là. Si vous pensez avoir besoin d'index de correspondances supplémentaires, vous devez utiliser une compréhension de liste ou une expression de générateur.

>>> [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é une fois index, j'utilise maintenant une compréhension de liste ou une expression de générateur car ils sont plus généralisables. Donc, si vous envisagez d'atteindre index, jetez un œil à ces excellentes fonctionnalités Python.

Lance si l'élément n'est pas présent dans la liste

Un appel à indexentraîne un ValueErrorsi 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 n'est peut-être pas présent dans la liste, vous devez soit

  1. Vérifiez d'abord avec item in my_list(approche claire et lisible), ou
  2. Enveloppez l' indexappel dans un try/exceptbloc qui prend ValueError(probablement plus rapide, au moins lorsque la liste à rechercher est longue et que l'élément est généralement présent.)

20
index renvoie le premier élément dont la valeur est "bar". Si "bar" existe deux fois dans la liste, vous ne trouverez jamais la clé de la deuxième "barre". Voir la documentation: docs.python.org/3/tutorial/datastructures.html
mpoletto

2
Si vous ne recherchez qu'un élément (le premier), j'ai trouvé que index()c'est un peu moins de 90% plus rapide que la compréhension de liste par rapport aux listes d'entiers.
slybloty

Quelle structure de données faut-il utiliser si la liste est très longue?
izhang05

@izhang: Un index auxillaire, comme un dict {element -> list_index}, si les éléments sont hachables et que la position dans la liste est importante.
Alex Coventry

899

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.


2
bpython est une manière conviviale et agréable de lire les documents de manière interactive.
goetzc

@davidavr oui, mais le reste d'entre nous qui veulent simplement le rechercher sur Google au lieu de faire défiler les documents d'aide n'auraient pas ce bel ensemble central et classé d'options. :)
honkaboy

556

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. Utilisation enumerate():

for i, j in enumerate(['foo', 'bar', 'baz']):
    if j == 'bar':
        print(i)

La index()fonction ne renvoie que la première occurrence, tandis qu'elle 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

L'énumération fonctionne mieux que les méthodes basées sur l'index pour moi, car je cherche à rassembler les indices des chaînes à l'aide de 'startswith ", et j'ai besoin de rassembler plusieurs occurrences. Ou existe-t-il un moyen d'utiliser l'index avec" démarre avec "que n'a pas pu comprendre
Tupelo Thistlehead

3
Entre mes mains, la version énumérée est toujours légèrement plus rapide. Certains détails de mise en œuvre peuvent avoir changé depuis la publication de la mesure ci-dessus.
Alex Coventry

2
Cela a déjà été répondu depuis '11: stackoverflow.com/questions/6294179/…
Cristik


132

index()renvoie le premier indice de valeur!

| index (...)
| L.index (value, [start, [stop]]) -> integer - 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"])

2
Et si n'existe pas dans la liste?
Peter Mortensen

1
Un élément inexistant soulèvera ValueError
Nam G VU

1
Cette réponse conviendrait mieux ici: stackoverflow.com/questions/6294179/…
Cristik

86

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


58

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

1
Cela nous aide à éviter d'essayer la capture!
devssh

Cependant, cela pourrait doubler la complexité. Quelqu'un at-il vérifié?
stefanct

@stefanct La complexité temporelle est toujours linéaire mais elle parcourra la liste deux fois.
ApproachingDarknessFish

@ApproachingDarknessFish C'est évidemment ce que je voulais dire. Même si, d'un point de vue pédagogique, c'est le même ordre de complexité, répéter deux fois pourrait être un grave inconvénient dans de nombreux cas d'utilisation, donc je l'ai évoqué. Et nous ne savons toujours pas la réponse ...
Stefanct

44

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?


9
La 3ème méthode parcourt deux fois la liste, non?
Eric Duminil

Re: "Toutes les fonctions proposées ici" : Au moment de la rédaction peut-être, mais vous devriez vérifier les réponses les plus récentes pour voir si cela est toujours vrai.
Peter Mortensen

41

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.


4
Qu'en est-il des listes de chaînes, des listes d'objets non numériques, etc ...?
Laryx Decidua

1
Cette réponse devrait être mieux publiée ici: stackoverflow.com/questions/6294179/…
Cristik

1
C'est le meilleur que j'ai lu. les tableaux numpy sont beaucoup plus efficaces que les listes Python. Si la liste est courte, cela ne pose aucun problème d'en faire une copie à partir d'une liste Python, si ce n'est pas le cas, le développeur devrait peut-être envisager de stocker les éléments dans le tableau numpy en premier lieu.
Athanassios

35

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 isou is notAucune:

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 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 pouvez é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 voulez 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]

Est-ce 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à, la capture ValueErrorest plutôt verbeuse - et je préfère éviter cela.

J'itère généralement sur la liste de toute façon, donc je garde généralement un pointeur sur toute information intéressante, obtenant l' index avec énumération.

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 que j'ai montrées.

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

Il y a beaucoup, beaucoup d'utilisations pour idlelib, dans l'interface graphique et l'analyse de texte.

Le keywordmodule 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 l'inactivité).

Bien qu'il existe des cas d'utilisation pour cela, 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.



21

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

Production


[1, 3, 5, 7]

Facile

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

Production:

0
4

1
Cette réponse devrait être mieux publiée ici: stackoverflow.com/questions/6294179/…
Cristik

16

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

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

1
Cette réponse devrait être mieux publiée ici: stackoverflow.com/questions/6294179/…
Cristik

15

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 renvoie 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 sa réponse précédente . Au moment où j'ai initialement répondu à cette question, je n'ai même pas vu 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 toujours pas de sens pour vous, je vous recommande fortement 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.


12

Une variante de la réponse de FMc et user7177 donnera un dict qui peut renvoyer 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.


1
Cette réponse devrait être mieux publiée ici: stackoverflow.com/questions/6294179/…
Cristik

10

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

9

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

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

4
Cela itère deux fois la baie, ce qui peut entraîner des problèmes de performances pour les baies de grande taille.
Cristik

Se mettre d'accord. Si les listes sont considérablement longues, je choisirais autre chose. Cela ne devrait pas être un gros problème pour les petites et moyennes listes.
Ketan

5

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


3
[i for i, j in enumerate (haystack) if j == 'needle'] est plus compact et plus lisible, je pense.
Giovanni G. PY,

5
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


4

La index()méthode Python génère une erreur si l'élément est introuvable. Donc, à la place, vous pouvez le rendre similaire à la indexOf()fonction de JavaScript qui retourne -1si l'article n'a pas été trouvé:

try:
    index = array.index('search_keyword')
except ValueError:
    index = -1

5
cependant, JavaScript a pour philosophie que les résultats étranges sont meilleurs que les erreurs, il est donc logique de renvoyer -1, mais en Python, il peut être difficile de retrouver un bug, car -1 renvoie un élément à la fin de la liste.
Sapphire_Brick

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

1
Cette réponse se sent à la maison Scala/ fonctionnels programmation amateurs
y2k-shubham

3

Donnons le nom lstà la liste que vous avez. On peut convertir la liste lsten un numpy array. Et, puis utilisez numpy.where pour obtenir l'index de l'élément choisi dans la liste. Voici comment 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

2

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 Alors, que fait exactement l'énumération? . Cela m'a aidé à comprendre.


2

Si vous allez trouver un index une fois, alors utiliser la méthode "index" est très bien. Cependant, si vous allez rechercher vos données plus d'une fois, je vous recommande d'utiliser le module bissect . Gardez à l'esprit que l'utilisation des données du module bissect doit être triée. Vous triez donc les données une fois et vous pouvez ensuite utiliser la bissect. L'utilisation du module bissect sur ma machine est environ 20 fois plus rapide que l'utilisation de la méthode d'indexation.

Voici un exemple de code utilisant Python 3.8 et la syntaxe ci-dessus:

import bisect
from timeit import timeit

def bisect_search(container, value):
    return (
      index 
      if (index := bisect.bisect_left(container, value)) < len(container) 
      and container[index] == value else -1
    )

data = list(range(1000))
# value to search
value = 666

# times to test
ttt = 1000

t1 = timeit(lambda: data.index(value), number=ttt)
t2 = timeit(lambda: bisect_search(data, value), number=ttt)

print(f"{t1=:.4f}, {t2=:.4f}, diffs {t1/t2=:.2f}")

Production:

t1=0.0400, t2=0.0020, diffs t1/t2=19.60

1

Si les performances sont préoccupantes:

Il est mentionné dans de nombreuses réponses que la méthode intégrée 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

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

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


0

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]

-1

à mon avis, ["foo", "bar", "baz"].index("bar")c'est bon mais ce n'est pas suffisant! car si "bar" n'est pas dans le dictionnaire, c'est ValueErrorsurélevé.

def find_index(arr, name):
    try:
        return arr.index(name)
    except ValueError:
        return -1

if __name__ == '__main__':
    print(find_index(["foo", "bar", "baz"], "bar"))

et le résultat est:

1

et si le nom n'était pas à l'arr, la fonction retourne -1.par exemple:

print (find_index (["foo", "bar", "baz"], "fooo"))

-1


1
Ne l'utilisez pas car l = [1, 2]; find_index(l, 3)reviendrait -1et l[find_index(l, 3)]reviendrait 2. -1 est une mauvaise chose à retourner, renvoyez simplement None.
Daniel Stracaboško

-1 est un contrat que vous pouvez renvoyer ce que vous voulez, mais essayez d'utiliser moins de None dans vos programmes, car None ou Null dans la communication de votre programme avec d'autres programmes comme les sites Web Android et PHP peut provoquer une rupture de programme, par exemple, vous pouvez retourner null en JSON et votre application de téléphone Web se fermera ou renverra l'erreur 500 (erreur de serveur interne).
NaabNuts
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.