Dada una lista ["foo", "bar", "baz"]
y un elemento en la lista "bar"
, ¿cómo obtengo su índice (1) en Python?
25 respuestas
Una variante en la respuesta de FMc y user7177 dará un dict 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 usar esto como una línea para obtener todos los índices de una sola entrada. No hay garantías de eficiencia, aunque sí utilicé set (a) para reducir la cantidad de veces que se llama al lambda.
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 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 lo llevará al método que está buscando.
Obtener todas las ocurrencias 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 que nuestra función encuentre index
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]
Sencilla
for n, i in enumerate([1, 2, 3, 4, 1]):
if i == 1:
print(n)
Salida:
0
4
Como lo indica @TerryA, muchas respuestas analizan cómo encontrar el índice one .
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
Encuentra índices de múltiples observaciones:
list(mit.locate(iterable, lambda x: x == "bar"))
# [1, 5]
Prueba múltiples artículos:
list(mit.locate(iterable, lambda x: x in {"bar", "ham"}))
# [1, 3, 5]
Consulte también más opciones con more_itertools.locate
. Instale a través de > pip install more_itertools
.
Para aquellos que vienen de otro idioma como yo, tal vez con un bucle simple 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.
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 explica si la cadena no está en la lista también, si no está en la lista, entonces location = -1
Encontrar el índice del elemento x en la lista L:
idx = L.index(x) if (x in L) else -1
a = ["foo","bar","baz",'bar','any','much']
indexes = [index for index in range(len(a)) if a[index] == 'bar']
Para obtener todos los índices:
indexes = [i for i,x in enumerate(xs) if x == 'foo']
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]
Démosle el nombre lst
a la lista que tiene. Uno puede convertir la lista lst
a numpy array
. Y luego utilice numpy.where para obtener el índice del elemento elegido en la lista. A continuación se detalla 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
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')
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
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))))))
Usando el diccionario, donde procesa la lista primero y luego 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]
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 y legible.
La mayoría de las respuestas explican cómo encontrar un solo índice , 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 ocurrencias.
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 más o menos 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
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
Dado que las listas de Python están basadas en cero, podemos usar la función integrada 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 elemento a buscar.
(Nota: Aquí estamos iterando usando i para obtener los índices, pero si necesitamos centrarnos en los elementos, podemos cambiar a j).
Esta solución no es tan poderosa como otras, pero si eres un principiante y solo conoces los for
bucles, aún es posible encontrar el primer índice de un elemento mientras evitas el ValueError:
def find_element(p,t):
i = 0
for e in p:
if e == t:
return i
else:
i +=1
return -1
Si el rendimiento es preocupante:
En numerosas respuestas se menciona que el método incorporado 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 ítems-í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]
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 quieres?
Para evitar ValueError, puede hacer una función para hacerlo, aunque una clase también funcionaría.
def findInList(List, item):
try:
return List.index(item)
except ValueError:
return -1
El único problema es que podría causar un error difícil de rastrear; lo mismo se aplicaría a otros números.
Sin embargo, si devuelve algo que no sea un número, probablemente se usará como un índice de lista e inevitablemente arrojará un error de todos modos.
En mi opinión, suponiendo que algo ha salido mal si no se encuentra el elemento, es mejor usar un try
- except
, pero con un mensaje de error personalizado y, por lo tanto, no dificultará la depuración, ni importará el valor de retorno:
# 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}.`")
El método Python index()
arroja un error si no se encontró el elemento. Por lo tanto, puede hacerlo similar a la función indexOf()
de JavaScript que devuelve -1
si no se encuentra el elemento:
try:
index = array.index('search_keyword')
except ValueError:
index = -1
Preguntas relacionadas
Nuevas preguntas
python
Python es un lenguaje de programación multipropósito, de tipificación dinámica y de múltiples paradigmas. Está diseñado para ser rápido de aprender, comprender y usar, y hacer cumplir una sintaxis limpia y uniforme. Tenga en cuenta que Python 2 está oficialmente fuera de soporte a partir del 01-01-2020. Aún así, para preguntas de Python específicas de la versión, agregue la etiqueta [python-2.7] o [python-3.x]. Cuando utilice una variante de Python (por ejemplo, Jython, PyPy) o una biblioteca (por ejemplo, Pandas y NumPy), inclúyala en las etiquetas.