Encontrar el índice de un elemento dado una lista que lo contiene en Python

Para una lista ["foo", "bar", "baz"] y un elemento en la lista "bar" , ¿cómo obtengo su índice (1) en Python?

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

Referencia: Estructuras de datos> Más en listas

Advertencias siguen

Tenga en cuenta que si bien esta es quizás la forma más limpia de responder la pregunta, el index es un componente bastante débil de la list API, y no puedo recordar la última vez que lo usé enojado. Se me indicó en los comentarios que, debido a que esta respuesta está muy referida, debería hacerse más completa. Algunas advertencias sobre list.index siguen. Probablemente valga la pena echarle un vistazo inicialmente a la cadena de documentación para ello:

 >>> print(list.index.__doc__) L.index(value, [start, [stop]]) -> integer -- return first index of value. Raises ValueError if the value is not present. 

Tiempo-complejidad lineal en longitud de lista

Una llamada de index verifica todos los elementos de la lista en orden, hasta que encuentra una coincidencia. Si su lista es larga y no sabe aproximadamente en qué lugar de la lista aparece, esta búsqueda podría convertirse en un cuello de botella. En ese caso, debe considerar una estructura de datos diferente. Tenga en cuenta que si sabe aproximadamente dónde encontrar la coincidencia, puede dar una pista al index . Por ejemplo, en este fragmento, l.index(999_999, 999_990, 1_000_000) es aproximadamente cinco órdenes de magnitud más rápido que l.index(999_999) directo l.index(999_999) , porque el primero solo tiene que buscar 10 entradas, mientras que el último busca un millón:

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

Solo devuelve el índice de la primera coincidencia a su argumento.

Una llamada para index busca en la lista en orden hasta que encuentra una coincidencia y se detiene allí. Si espera necesitar índices de más coincidencias, debe usar una lista de comprensión o expresión de generador.

 >>> [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 mayoría de los lugares en los que alguna vez hubiera usado el index , ahora uso una comprensión de lista o una expresión generadora porque son más generalizables. Por lo tanto, si está considerando alcanzar el index , eche un vistazo a estas excelentes características de Python.

Lanza si el elemento no está presente en la lista.

Una llamada para index da como resultado un ValueError si el elemento no está presente.

 >>> [1, 1].index(2) Traceback (most recent call last): File "", line 1, in  ValueError: 2 is not in list 

Si el elemento puede no estar presente en la lista, debe

  1. Verifíquelo primero con el item in my_list (enfoque limpio y legible), o
  2. Envuelva la llamada de index en un bloque try/except que atrapa ValueError (probablemente más rápido, al menos cuando la lista de búsqueda es larga, y el elemento generalmente está presente).

Una cosa que es realmente útil para aprender Python es usar la función de ayuda interactiva:

 >>> help(["foo", "bar", "baz"]) Help on list object: class list(object) ... | | index(...) | L.index(value, [start, [stop]]) -> integer -- return first index of value | 

que a menudo te llevará al método que estás buscando.

La mayoría de las respuestas explican cómo encontrar un índice único , pero sus métodos no devuelven múltiples índices si el elemento está en la lista varias veces. Utilice enumerate() :

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

La función index() solo devuelve la primera aparición, mientras que enumerate() devuelve todas las apariciones.

Como una lista de comprensión:

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

Aquí también hay otra pequeña solución con itertools.count() (que es prácticamente el mismo enfoque que enumerar):

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

Esto es más eficiente para listas más grandes que usar 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 

Para obtener todos los índices:

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

index() devuelve el primer índice de valor!

| índice(…)
| L.index (valor, [inicio, [detener]]) -> entero – devuelve el primer índice de valor

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

Surgirá un problema si el elemento no está en la lista. Esta función maneja el problema:

 # if element is found it returns index of element else returns None def find_element_in_list(element, list_element): try: index_element = list_element.index(element) return index_element except ValueError: return None 
 a = ["foo","bar","baz",'bar','any','much'] indexes = [index for index in range(len(a)) if a[index] == 'bar'] 

Debe establecer una condición para verificar si el elemento que está buscando está en la lista

 if 'your_element' in mylist: print mylist.index('your_element') else: print None 

Todas las funciones propuestas aquí reproducen el comportamiento inherente del lenguaje pero ocultan lo que está sucediendo.

 [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 

¿Por qué escribir una función con manejo de excepciones si el lenguaje proporciona los métodos para hacer lo que usted desea?

Si desea todos los índices, puede usar 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),) 

Es una solución clara, legible.

Encontrar el índice de un elemento dado una lista que lo contiene en Python

Para una lista ["foo", "bar", "baz"] y un elemento en la lista "bar" , ¿cuál es la forma más limpia de obtener su índice (1) en Python?

Bueno, seguro, está el método de índice, que devuelve el índice de la primera aparición:

 >>> l = ["foo", "bar", "baz"] >>> l.index('bar') 1 

Hay un par de problemas con este método:

  • Si el valor no está en la lista, obtendrás un ValueError
  • Si hay más de uno de los valores en la lista, solo obtendrá el índice del primero.

Sin valores

Si el valor puede faltar, debe capturar el ValueError .

Puedes hacerlo con una definición reutilizable como esta:

 def index(a_list, value): try: return a_list.index(value) except ValueError: return None 

Y úsalo así:

 >>> print(index(l, 'quux')) None >>> print(index(l, 'bar')) 1 

Y la desventaja de esto es que probablemente tendrá una verificación de si el valor devuelto is o is not Ninguno:

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

Más de un valor en la lista

Si pudiera tener más incidencias, no obtendrá información completa con list.index :

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

Podría enumerar en una lista la comprensión de los índices:

 >>> [index for index, v in enumerate(l) if v == 'bar'] [1, 3] >>> [index for index, v in enumerate(l) if v == 'boink'] [] 

Si no tiene incidencias, puede verificarlo con una verificación booleana del resultado, o simplemente no hacer nada si repite los resultados:

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

Mejores datos de munging con pandas.

Si tiene pandas, puede obtener fácilmente esta información con un objeto de la serie:

 >>> import pandas as pd >>> series = pd.Series(l) >>> series 0 foo 1 bar 2 baz 3 bar dtype: object 

Una comprobación de comparación devolverá una serie de valores booleanos:

 >>> series == 'bar' 0 False 1 True 2 False 3 True dtype: bool 

Pase esa serie de booleanos a la serie a través de la notación de subíndices, y obtendrá solo los miembros coincidentes:

 >>> series[series == 'bar'] 1 bar 3 bar dtype: object 

Si solo desea los índices, el atributo de índice devuelve una serie de enteros:

 >>> series[series == 'bar'].index Int64Index([1, 3], dtype='int64') 

Y si los quiere en una lista o tupla, simplemente páselos al constructor:

 >>> list(series[series == 'bar'].index) [1, 3] 

Sí, también podría usar una lista de comprensión con enumeración, pero eso no es tan elegante, en mi opinión, está haciendo pruebas de igualdad en Python, en lugar de dejar que el código incorporado escrito en C lo maneje:

 >>> [i for i, value in enumerate(l) if value == 'bar'] [1, 3] 

¿Es este un problema XY ?

El problema XY está preguntando acerca de su bash de solución en lugar de su problema real.

¿Por qué crees que necesitas el índice dado un elemento en una lista?

Si ya conoce el valor, ¿por qué le importa dónde está en una lista?

Si el valor no está allí, capturar el ValueError es bastante detallado, y prefiero evitarlo.

Por lo general, estoy iterando sobre la lista, así que generalmente mantendré un puntero a cualquier información interesante y obtendré el índice con la enumeración.

Si está mezclando datos, probablemente debería usar pandas, que tiene herramientas mucho más elegantes que las soluciones de Python puras que he mostrado.

No recuerdo haber necesitado list.index , yo mismo. Sin embargo, he revisado la biblioteca estándar de Python y veo algunos usos excelentes para ella.

Hay muchos, muchos usos para ello en idlelib , para la GUI y el análisis de texto.

El módulo de keyword utiliza para encontrar marcadores de comentarios en el módulo para regenerar automáticamente la lista de palabras clave en él a través de la metaprogtwigción.

En Lib / buzon.py parece estar usándolo como una asignación ordenada:

 key_list[key_list.index(old)] = new 

y

 del key_list[key_list.index(key)] 

En Lib / http / cookiejar.py, parece ser usado para obtener el próximo mes:

 mon = MONTHS_LOWER.index(mon.lower())+1 

En Lib / tarfile.py similar a distutils para obtener una porción de un elemento:

 members = members[:members.index(tarinfo)] 

En Lib / pickletools.py:

 numtopop = before.index(markobject) 

Lo que estos usos parecen tener en común es que parecen operar en listas de tamaños restringidos (importante debido al tiempo de búsqueda O (n) para list.index ), y se utilizan principalmente en el análisis (y la interfaz de usuario en el caso de Ocioso).

Si bien hay casos de uso para ello, son bastante infrecuentes. Si busca esta respuesta, pregúntese si lo que está haciendo es el uso más directo de las herramientas proporcionadas por el idioma para su caso de uso.

Todos los índices con la función 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') 

Obtención de todas las apariciones y la posición de uno o más elementos (idénticos) en una lista

Con enumerate (alist) puede almacenar el primer elemento (n) que es el índice de la lista cuando el elemento x es igual a lo que busca.

 >>> alist = ['foo', 'spam', 'egg', 'foo'] >>> foo_indexes = [n for n,x in enumerate(alist) if x=='foo'] >>> foo_indexes [0, 3] >>> 

Hagamos nuestra función de encontrar índice.

Esta función toma el elemento y la lista como argumentos y devuelve la posición del elemento en la lista, como vimos antes.

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

Salida


 [1, 3, 5, 7] 

Sencillo

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

Salida:

 0 4 

Simplemente puedes ir con

 a = [['hand', 'head'], ['phone', 'wallet'], ['lost', 'stock']] b = ['phone', 'lost'] res = [[x[0] for x in a].index(y) for y in b] 

Otra opció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] >>> 

Una variante en la respuesta de FMc y user7177 dará un dictado que puede devolver todos los índices para cualquier entrada:

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

También puede utilizar esto como un solo forro para obtener todos los índices para una sola entrada. No hay garantías de eficiencia, aunque sí utilicé el conjunto (a) para reducir el número de veces que se llama a la lambda.

Y ahora para algo completamente diferente…

… como confirmar la existencia del elemento antes de obtener el índice. Lo bueno de este enfoque es que la función siempre devuelve una lista de índices, incluso si es una lista vacía. Funciona con cuerdas también.

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

Cuando se pega en una ventana interactiva de 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] >>> 

Actualizar

Después de otro año de desarrollo de python cara a cara, mi respuesta original me da un poco de vergüenza, por lo que para aclarar las cosas, uno puede usar el código anterior; sin embargo, la forma mucho más idiomática de obtener el mismo comportamiento sería utilizar la comprensión de lista, junto con la función enumerate ().

Algo como esto:

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

Que, cuando se pega en una ventana interactiva de python produce:

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

Y ahora, después de revisar esta pregunta y todas las respuestas, me doy cuenta de que esto es exactamente lo que FMc sugirió en su respuesta anterior . En el momento en que respondí originalmente a esta pregunta, ni siquiera vi esa respuesta porque no la entendí. Espero que mi ejemplo un poco más detallado ayude a la comprensión.

Si la línea de código que aparece arriba todavía no tiene sentido para usted, le recomiendo encarecidamente la “comprensión de la lista de python” de Google y dedique unos minutos a familiarizarse. Es solo una de las muchas funciones poderosas que hacen que sea un placer usar Python para desarrollar código.

Esta solución no es tan poderosa como otras, pero si usted es un principiante y solo conoce los bucles, todavía es posible encontrar el primer índice de un elemento y evitar el ValueError:

 def find_element(p,t): i = 0 for e in p: if e == t: return i else: i +=1 return -1 
 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) 

Esto cuenta si la cadena no está en la lista también, si no está en la lista, entonces la ubicación es = -1

Dado que las listas de Python están basadas en cero, podemos usar la función incorporada de zip de la siguiente manera:

 >>> [i for i,j in zip(range(len(haystack)), haystack) if j == 'needle' ] 

donde “pajar” es la lista en cuestión y “aguja” es el ítem a buscar.

(Nota: aquí estamos iterando usando i para obtener los índices, pero si necesitamos centrarnos en los elementos, podemos cambiar a j).

Hay una respuesta más funcional a esto.

 list(filter(lambda x: x[1]=="bar",enumerate(["foo", "bar", "baz", "bar", "baz", "bar", "a", "b", "c"]))) 

Forma más genérica:

 def get_index_of(lst, element): return list(map(lambda x: x[0],\ (list(filter(lambda x: x[1]==element, enumerate(lst)))))) 

El método de index() Python index() emite un error si no se encontró el elemento, ¡lo cual apesta!

Entonces, en lugar de eso, puede hacerlo similar a la función indexOf() de JavaScript que devuelve -1 si no se encontró el elemento:

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

Encontrando el índice del artículo x en la lista L:

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

Hay dos posibilidades si la lista no tiene elementos repetidos que necesita revisar el índice para

  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 es repetido significa que solo te dará el primer índice.

Si necesita obtener todo el índice donde está presente el artículo significa

 eg: li=[10,20,30,20,40, 50, 10] # here need to get index of 20 means its have 2 index (1,3) 

para conseguir eso necesitas hacerlo como

  li=[10,20,30,20,40, 50, 10] [i for i, e in enumerate(li) if e == 20] 

entonces obtendrás una lista de índice como o / p like [1,3]

Démosle el nombre lst a la lista que tienes. Uno puede convertir la lista numpy array a una numpy array . Y, a continuación, utilice numpy.where para obtener el índice del elemento elegido en la lista. A continuación se muestra la forma en que lo implementará.

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

Para aquellos que vienen de otro idioma como yo, tal vez con un simple bucle es más fácil de entender y usar:

 mylist = ["foo", "bar", "baz", "bar"] newlist = enumerate(mylist) for index, item in newlist: if item == "bar": print(index, item) 

Estoy agradecido por Entonces, ¿qué hace exactamente enumerar? . Eso me ayudó a entender.

Si el desempeño es preocupante:

Se menciona en numerosas respuestas que el método list.index(item) del método list.index(item) es un algoritmo O (n). Está bien si necesita realizar esto una vez. Pero si necesita acceder a los índices de elementos varias veces, tiene más sentido crear primero un diccionario (O (n)) de pares de elementos de índice, y luego acceder al índice en O (1) cada vez que lo necesite. eso.

Si está seguro de que los elementos de su lista nunca se repiten, puede:

 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 puede tener elementos duplicados, y necesita devolver todos sus índices:

 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] 

Según lo indicado por @TerryA, muchas respuestas discuten cómo encontrar un índice.

more_itertools es una biblioteca de terceros con herramientas para localizar múltiples índices dentro de un iterable.

Dado

 import more_itertools as mit iterable = ["foo", "bar", "baz", "ham", "foo", "bar", "baz"] 

Código

Encontrar índices de observaciones múltiples:

 list(mit.locate(iterable, lambda x: x == "bar")) # [1, 5] 

Prueba varios artículos:

 list(mit.locate(iterable, lambda x: x in {"bar", "ham"})) # [1, 3, 5] 

Ver también más opciones con more_itertools.locate . Instalar via > pip install more_itertools .

utilizando el diccionario, donde primero se procesa la lista y luego se le agrega el índice

 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]