Encuentra un valor en una lista [duplicado]

Resuelto Stephane Rolland asked hace 12 años • 14 respuestas

Utilizo lo siguiente para comprobar si itemestá en my_list:

if item in my_list:
    print("Desired item is in list")

Es "if item in my_list: " la forma más "pitónica" de encontrar un elemento en una lista?

EDITAR PARA REABRIR: la pregunta se ha considerado duplicada, pero no estoy del todo convencido: aquí esta pregunta es más o menos "¿cuál es el más pitónico? " de encontrar un elemento en una lista". Y la primera respuesta a la pregunta es realmente extensa en todas las formas en Python de hacer esto.

Mientras que en la pregunta duplicada vinculada y su respuesta correspondiente, el enfoque se limita aproximadamente solo a la palabra clave 'in' en Python. Creo que es realmente limitante, en comparación con la pregunta actual.

Y creo que la respuesta a esta pregunta actual es más relevante y elaborada que la respuesta de la pregunta/respuesta duplicada propuesta.

Stephane Rolland avatar Mar 03 '12 09:03 Stephane Rolland
Aceptado

En cuanto a su primera pregunta: " if item is in my_list:" está perfectamente bien y debería funcionar si itemes igual a uno de los elementos internos my_list. El elemento debe coincidir exactamente con un elemento de la lista. Por ejemplo, "abc"y "ABC"no coinciden. En particular, los valores de coma flotante pueden sufrir imprecisiones. Por ejemplo, 1 - 1/3 != 2/3.

En cuanto a su segunda pregunta: en realidad, hay varias formas posibles de "encontrar" cosas en listas.

Comprobando si hay algo dentro

Este es el caso de uso que usted describe: comprobar si algo está dentro de una lista o no. Como sabes, puedes utilizar el inoperador para eso:

3 in [1, 2, 3] # => True

Filtrar una colección

Es decir, encontrar todos los elementos de una secuencia que cumplan una determinada condición. Puede utilizar listas de comprensión o expresiones generadoras para eso:

matches = [x for x in lst if fulfills_some_condition(x)]
matches = (x for x in lst if x > 6)

Este último devolverá un generador que puede imaginar como una especie de lista diferida que solo se creará tan pronto como la repita. Por cierto, el primero es exactamente equivalente a

matches = filter(fulfills_some_condition, lst)

en Python 2. Aquí puede ver funciones de orden superior en funcionamiento. En Python 3, filterno devuelve una lista, sino un objeto similar a un generador.

Encontrar la primera ocurrencia

Si solo desea lo primero que coincida con una condición (pero aún no sabe qué es), está bien usar un bucle for (posiblemente usando elsetambién la cláusula, que no es muy conocida). También puedes usar

next(x for x in lst if ...)

que devolverá la primera coincidencia o generará un StopIterationsi no se encuentra ninguno. Alternativamente, puedes usar

next((x for x in lst if ...), [default value])

Encontrar la ubicación de un artículo

Para las listas, también existe el indexmétodo que a veces puede resultar útil si desea saber dónde se encuentra un determinado elemento en la lista:

[1,2,3].index(2) # => 1
[1,2,3].index(4) # => ValueError

Sin embargo, tenga en cuenta que si tiene duplicados, .indexsiempre devuelve el índice más bajo:......

[1,2,3,2].index(2) # => 1

Si hay duplicados y desea todos los índices, puede utilizar enumerate()en su lugar:

[i for i,x in enumerate([1,2,3,2]) if x==2] # => [1, 3]
Niklas B. avatar Mar 03 '2012 02:03 Niklas B.

Si desea encontrar un elemento o Noneutilizar el valor predeterminado en next, no aparecerá StopIterationsi el elemento no se encontró en la lista:

first_or_default = next((x for x in lst if ...), None)
Janusz Skonieczny avatar Apr 24 '2012 17:04 Janusz Skonieczny

Si bien la respuesta de Niklas B. es bastante completa, cuando queremos encontrar un elemento en una lista, a veces resulta útil obtener su índice:

next((i for i, x in enumerate(lst) if [condition on x]), [default value])
Vincent Cantin avatar Dec 04 '2015 06:12 Vincent Cantin

Encontrar la primera ocurrencia

Hay una receta para eso en itertools:

def first_true(iterable, default=False, pred=None):
    """Returns the first true value in the iterable.

    If no true value is found, returns *default*

    If *pred* is not None, returns the first item
    for which pred(item) is true.

    """
    # first_true([a,b,c], x) --> a or b or c or x
    # first_true([a,b], x, f) --> a if f(a) else b if f(b) else x
    return next(filter(pred, iterable), default)

Por ejemplo, el siguiente código encuentra el primer número impar en una lista:

>>> first_true([2,3,4,5], None, lambda x: x%2==1)
3  

Puedes copiarlo/pegarlo o instalarlo.more-itertools

pip3 install more-itertools

donde ya está incluida esta receta.

Antony Hatchkins avatar Jan 07 '2018 19:01 Antony Hatchkins

Otra alternativa: puedes comprobar si un artículo está en una lista con if item in list:, pero este es el orden O(n). Si está tratando con listas grandes de elementos y todo lo que necesita saber es si algo es miembro de su lista, primero puede convertir la lista en un conjunto y aprovechar la búsqueda de conjuntos en tiempo constante :

my_set = set(my_list)
if item in my_set:  # much faster on average than using a list
    # do something

No será la solución correcta en todos los casos, pero en algunos casos esto podría brindarle un mejor rendimiento.

Tenga en cuenta que crear el conjunto con set(my_list)también es O(n), por lo que si solo necesita hacer esto una vez, no es más rápido hacerlo de esta manera. Sin embargo, si necesita verificar la membresía repetidamente, entonces esto será O(1) para cada búsqueda después de la creación del conjunto inicial.

Engineero avatar Sep 04 '2018 15:09 Engineero