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.
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:
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:2isnotin list
Si l'élément n'est peut-être pas présent dans la liste, vous devez soit
Vérifiez d'abord avec item in my_list(approche claire et lisible), ou
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.)
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.
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.
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 Nonedef find_element_in_list(element, list_element):try:
index_element = list_element.index(element)return index_element
exceptValueError:returnNone
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 elseNone# 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?
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 :
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:
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 isnotNone:
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'0False1True2False3True
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:
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]
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.
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)
>>> 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]>>>
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 =0while val in l[last:]:
i = l[last:].index(val)
retval.append(last + i)
last += i +1return 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:
Python2.7.6(v2.7.6:3a1db0d2747e,Nov102013,00:42:54)[GCC 4.2.1(AppleInc. 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:
Python2.7.14|Anaconda,Inc.|(default,Dec72017,11:07:58)[GCC 4.2.1CompatibleClang4.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.
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.
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 =0for e in p:if e == t:return i
else:
i +=1return-1
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.)
[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=-1print(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
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')exceptValueError:
index =-1
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.
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 typeprint np.where( np.array(lst)=='bar')[0][0]>>>1
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}")
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]
à 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é.
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).
"bar"
, [2] Tous les indices de"bar"
?Réponses:
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 ,
index
c'est un composant plutôt faible de l'list
API, 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 delist.index
suivre. Il vaut probablement la peine de jeter un coup d'œil à la documentation:Complexité temporelle linéaire en longueur de liste
Un
index
appel 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 donnerindex
un indice. Par exemple, dans cet extrait,l.index(999_999, 999_990, 1_000_000)
est environ cinq ordres de grandeur plus rapide que droitl.index(999_999)
, car le premier n'a qu'à rechercher 10 entrées, tandis que le second en recherche un million:Renvoie uniquement l'index de la première correspondance à son argument
Un appel à
index
recherche 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.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'atteindreindex
, jetez un œil à ces excellentes fonctionnalités Python.Lance si l'élément n'est pas présent dans la liste
Un appel à
index
entraîne unValueError
si l'élément n'est pas présent.Si l'élément n'est peut-être pas présent dans la liste, vous devez soit
item in my_list
(approche claire et lisible), ouindex
appel dans untry/except
bloc qui prendValueError
(probablement plus rapide, au moins lorsque la liste à rechercher est longue et que l'élément est généralement présent.)la source
index()
c'est un peu moins de 90% plus rapide que la compréhension de liste par rapport aux listes d'entiers.Une chose qui est vraiment utile pour apprendre Python est d'utiliser la fonction d'aide interactive:
ce qui vous mènera souvent à la méthode que vous recherchez.
la source
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()
:La
index()
fonction ne renvoie que la première occurrence, tandis qu'elleenumerate()
renvoie toutes les occurrences.En tant que compréhension de liste:
Voici également une autre petite solution avec
itertools.count()
(qui est à peu près la même approche que celle énumérée):C'est plus efficace pour des listes plus grandes que d'utiliser
enumerate()
:la source
Pour obtenir tous les index:
la source
index()
renvoie le premier indice de valeur!la source
Un problème surviendra si l'élément n'est pas dans la liste. Cette fonction gère le problème:
la source
la source
Vous devez définir une condition pour vérifier si l'élément que vous recherchez est dans la liste
la source
Toutes les fonctions proposées ici reproduisent le comportement du langage inhérent mais obscurcissent ce qui se passe.
Pourquoi écrire une fonction avec gestion des exceptions si le langage fournit les méthodes pour faire ce que vous voulez lui-même?
la source
Si vous voulez tous les index, vous pouvez utiliser NumPy :
C'est une solution claire et lisible.
la source
Eh bien, bien sûr, il y a la méthode index, qui retourne l'index de la première occurrence:
Il y a quelques problèmes avec cette méthode:
ValueError
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:
Et utilisez-le comme ceci:
Et l'inconvénient est que vous devrez probablement vérifier si la valeur retournée
is
ouis not
Aucune: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
:Vous pouvez énumérer dans une liste la compréhension des index:
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:
Meilleure fusion des données avec les pandas
Si vous avez des pandas, vous pouvez facilement obtenir ces informations avec un objet Series:
Une vérification de comparaison renverra une série de booléens:
Passez cette série de booléens à la série via la notation en indice, et vous obtenez uniquement les membres correspondants:
Si vous voulez uniquement les index, l'attribut index renvoie une série d'entiers:
Et si vous les voulez dans une liste ou un tuple, passez-les simplement au constructeur:
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:
Est-ce un problème XY ?
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
ValueError
est 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.index
moi-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
keyword
module 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é:
et
Dans Lib / http / cookiejar.py, semble être utilisé pour obtenir le mois prochain:
Dans Lib / tarfile.py similaire à distutils pour obtenir une tranche jusqu'à un élément:
Dans Lib / pickletools.py:
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.
la source
Tous les index avec la
zip
fonction:la source
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.
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.
Production
Facile
Production:
la source
Vous pouvez simplement y aller avec
la source
Une autre option
la source
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.
Une fois collé dans une fenêtre python interactive:
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:
Ce qui, une fois collé dans une fenêtre python interactive, donne:
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.
la source
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:
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.
la source
Cette solution n'est pas aussi puissante que les autres, mais si vous êtes débutant et ne connaissez que les
for
boucles, il est toujours possible de trouver le premier index d'un élément tout en évitant la ValueError:la source
Recherche de l'index de l'élément x dans la liste L:
la source
Étant donné que les listes Python sont basées sur zéro, nous pouvons utiliser la fonction intégrée zip comme suit:
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.)
la source
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
la source
La
index()
méthode Python génère une erreur si l'élément est introuvable. Donc, à la place, vous pouvez le rendre similaire à laindexOf()
fonction de JavaScript qui retourne-1
si l'article n'a pas été trouvé:la source
Il y a une réponse plus fonctionnelle à cela.
Forme plus générique:
la source
Scala
/ fonctionnels programmation amateursDonnons le nom
lst
à la liste que vous avez. On peut convertir la listelst
en unnumpy 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.la source
Pour ceux qui viennent d'une autre langue comme moi, peut-être qu'avec une simple boucle c'est plus facile à comprendre et à utiliser:
Je suis reconnaissant pour Alors, que fait exactement l'énumération? . Cela m'a aidé à comprendre.
la source
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:
Production:
la source
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:
Si vous pouvez avoir des éléments en double et devez renvoyer tous leurs indices:
la source
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é
Code
Trouver des indices d'observations multiples:
Testez plusieurs éléments:
Voir aussi plus d'options avec
more_itertools.locate
. Installez via> pip install more_itertools
.la source
en utilisant le dictionnaire, où traiter d'abord la liste, puis y ajouter l'index
la source
à 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'estValueError
surélevé.et le résultat est:
et si le nom n'était pas à l'arr, la fonction retourne -1.par exemple:
la source
l = [1, 2]; find_index(l, 3)
reviendrait-1
etl[find_index(l, 3)]
reviendrait2
. -1 est une mauvaise chose à retourner, renvoyez simplement None.