Estoy un poco confundido con esta pregunta: ¿desea buscar un elemento de forma recursiva en todos los niveles de una lista multidimensional, o solo desea buscar ocurrencias en el nivel superior de la lista?
Anderson Green
22
En mi opinión, debería haber un método de lista que haga exactamente esto.
otocan
Respuestas:
545
Puedes usar una lista de comprensión:
indices =[i for i, x in enumerate(my_list)if x =="whatever"]
En pitones anteriores, use filter () para esencialmente la misma funcionalidad.
Gleno
44
Las comprensiones de la lista aparecieron en python en 2.0, enumerateen 2.3. Entonces sí, si tu Python es antiguo, úsalo filter().
Steven Rumbalski
2
Esta técnica no encontrará todas las apariciones de un elemento en una matriz multidimensional. Por ejemplo, print([i for i, x in enumerate([[1,1],[0,1]]) if x == 1])devuelve en []lugar de [[0, 1], [0, 0], [1, 1]].
Anderson Green
10
@AndersonGreen: El término "matriz multidimensional" sugiere una estructura de datos que garantiza un tamaño uniforme a lo largo de cada uno de sus ejes. No existe tal estructura de datos en Python simple. Hay listas de listas, pero son muy diferentes de las "matrices multidimensionales". Si desea lo último, debería considerar usar NumPy, que le permite hacer cosas como (a == 1).nonzero()una matriz NumPy a.
Sven Marnach
2
@MadmanLee Si quieres algo rápido, usa NumPy. Ver la respuesta de JoshAdel
Georgy
117
Si bien no es una solución para las listas directamente, numpyrealmente brilla para este tipo de cosas:
import numpy as np
values = np.array([1,2,3,1,2,4,5,6,3,2,1])
searchval =3
ii = np.where(values == searchval)[0]
devoluciones:
ii ==>array([2,8])
Esto puede ser significativamente más rápido para listas (matrices) con una gran cantidad de elementos frente a algunas de las otras soluciones.
Noté que el [0] al final convierte lo que sería una matriz en una cadena. Tengo curiosidad por qué elegiste hacer esto.
amelia
55
@amelia [0]es necesaria porque wheredevuelve una tupla(array([2, 8], dtype=int64),)
Winand
1
Hola @Winand, puse [0] pero aún obtengo ambas partes. Aquí está mi código: (nrg.local_logs.all_id_resp_address es una lista) "ste =" 199.38.164.165 "value = np.where (nrg.local_logs.all_id_resp_address == ste) [0]" Seré feliz si puedes decirlo lo que hice mal
Tomer
2
@Tomer en primer lugar all_id_resp_addressdebería ser np.arrayno list.
Winand
1
@Tomer intentaste comparar listy str, obviamente, pasaste Falsea np.where. Cuando lo comparas np.arraycon algo. obtienes una matriz de valores booleanos. Luego np.whereencuentra posiciones de todos los Truevalores de esa matriz.
Winand
29
Una solución usando list.index:
def indices(lst, element):
result =[]
offset =-1whileTrue:try:
offset = lst.index(element, offset+1)exceptValueError:return result
result.append(offset)
Es mucho más rápido que la comprensión de la lista enumerate, para listas grandes. También es mucho más lento que la numpysolución si ya tiene la matriz, de lo contrario, el costo de la conversión supera la ganancia de velocidad (probado en listas enteras con 100, 1000 y 10000 elementos).
NOTA: Una nota de precaución basada en el comentario de Chris_Rands: esta solución es más rápida que la comprensión de la lista si los resultados son lo suficientemente escasos, pero si la lista tiene muchas instancias del elemento que se está buscando (más del ~ 15% de la lista , en una prueba con una lista de 1000 enteros), la comprensión de la lista es más rápida.
Dices que esto es más rápido que una lista de compilación, ¿puedes mostrar tus tiempos que lo demuestren?
Chris_Rands
55
Esto fue hace mucho tiempo, probablemente lo usé timeit.timeitcon listas generadas aleatoriamente. Sin embargo, ese es un punto importante, y supongo que esa puede ser la razón por la que preguntas. En ese momento no se me ocurrió, pero las ganancias de velocidad solo son ciertas si los resultados son lo suficientemente escasos. Acabo de probar con una lista llena del elemento para buscar, y es mucho más lento que la comprensión de la lista.
Paulo Almeida el
18
Qué tal si:
In[1]: l=[1,2,3,4,3,2,5,6,7]In[2]:[i for i,val in enumerate(l)if val==3]Out[2]:[2,4]
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]
Simple
for n, i in enumerate([1,2,3,4,1]):if i ==1:print(n)
Esta respuesta fue la más fácil de implementar en mi código existente.
Ryan Harris
2
Usando un for-loop:
Las respuestas con enumeratey una comprensión de la lista son más eficientes y pitónicas, sin embargo, esta respuesta está dirigida a estudiantes a quienes no se les permite usar algunas de esas funciones integradas .
crear una lista vacía indices
crea el ciclo con for i in range(len(x)):, que esencialmente itera a través de una lista de ubicaciones de índice[0, 1, 2, 3, ..., len(x)-1]
en el bucle, agregue cualquiera i, donde x[i]es una coincidencia para value, paraindices
def get_indices(x: list, value: int)-> list:
indices = list()for i in range(len(x)):if x[i]== value:
indices.append(i)return indices
n =[1,2,3,-50,-60,0,6,9,-60,-60]print(get_indices(n,-60))>>>[4,8,9]
Las funciones, get_indicesse implementan con sugerencias de tipo . En este caso, la lista, nes un grupo de ints, por lo tanto, buscamos value, también definido como un int.
Usando a while-loopy .index:
Con .index, use try-exceptpara el manejo de errores porque ValueErrorocurrirá si valueno está en la lista.
def get_indices(x: list, value: int)-> list:
indices = list()
i =0whileTrue:try:# find an occurrence of value and update i to that index
i = x.index(value, i)# add i to the list
indices.append(i)# advance i by 1
i +=1exceptValueErroras e:breakreturn indices
print(get_indices(n,-60))>>>[4,8,9]
Respuestas:
Puedes usar una lista de comprensión:
fuente
enumerate
en 2.3. Entonces sí, si tu Python es antiguo, úsalofilter()
.print([i for i, x in enumerate([[1,1],[0,1]]) if x == 1])
devuelve en[]
lugar de[[0, 1], [0, 0], [1, 1]]
.(a == 1).nonzero()
una matriz NumPya
.Si bien no es una solución para las listas directamente,
numpy
realmente brilla para este tipo de cosas:devoluciones:
Esto puede ser significativamente más rápido para listas (matrices) con una gran cantidad de elementos frente a algunas de las otras soluciones.
fuente
[0]
es necesaria porquewhere
devuelve una tupla(array([2, 8], dtype=int64),)
all_id_resp_address
debería sernp.array
nolist
.list
ystr
, obviamente, pasasteFalse
anp.where
. Cuando lo comparasnp.array
con algo. obtienes una matriz de valores booleanos. Luegonp.where
encuentra posiciones de todos losTrue
valores de esa matriz.Una solución usando
list.index
:Es mucho más rápido que la comprensión de la lista
enumerate
, para listas grandes. También es mucho más lento que lanumpy
solución si ya tiene la matriz, de lo contrario, el costo de la conversión supera la ganancia de velocidad (probado en listas enteras con 100, 1000 y 10000 elementos).NOTA: Una nota de precaución basada en el comentario de Chris_Rands: esta solución es más rápida que la comprensión de la lista si los resultados son lo suficientemente escasos, pero si la lista tiene muchas instancias del elemento que se está buscando (más del ~ 15% de la lista , en una prueba con una lista de 1000 enteros), la comprensión de la lista es más rápida.
fuente
timeit.timeit
con listas generadas aleatoriamente. Sin embargo, ese es un punto importante, y supongo que esa puede ser la razón por la que preguntas. En ese momento no se me ocurrió, pero las ganancias de velocidad solo son ciertas si los resultados son lo suficientemente escasos. Acabo de probar con una lista llena del elemento para buscar, y es mucho más lento que la comprensión de la lista.Qué tal si:
fuente
fuente
more_itertools.locate
encuentra índices para todos los artículos que satisfacen una condición.more_itertools
es una biblioteca de terceros> pip install more_itertools
.fuente
conda install
se ha vuelto muy inestable en el rendimiento últimamente)Una solución más (lo siento si hay duplicados) para todas las ocurrencias:
fuente
O use
range
(python 3):Para (pitón 2):
Y luego (ambos casos):
Es como se esperaba.
fuente
Usando filter () en python2.
fuente
Puedes crear un defaultdict
fuente
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.
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.
Salida
Simple
Salida:
fuente
Usando un
for-loop
:enumerate
y una comprensión de la lista son más eficientes y pitónicas, sin embargo, esta respuesta está dirigida a estudiantes a quienes no se les permite usar algunas de esas funciones integradas .indices
for i in range(len(x)):
, que esencialmente itera a través de una lista de ubicaciones de índice[0, 1, 2, 3, ..., len(x)-1]
i
, dondex[i]
es una coincidencia paravalue
, paraindices
x[i]
accede a la lista por índiceget_indices
se implementan con sugerencias de tipo . En este caso, la lista,n
es un grupo deint
s, por lo tanto, buscamosvalue
, también definido como unint
.Usando a
while-loop
y.index
:.index
, usetry-except
para el manejo de errores porqueValueError
ocurrirá sivalue
no está en la lista.fuente
get_indeices
es un poco más rápido (~ 15%) que la comprensión normal de la lista. Estoy tratando de resolverlo.Si está utilizando Python 2, puede lograr la misma funcionalidad con esto:
¿Dónde
my_list
está la lista de la que desea obtener los índices yvalue
es el valor buscado? Uso:fuente
Si necesita buscar todas las posiciones de los elementos entre ciertos índices , puede indicarlos:
fuente