Python: Buscar en la lista


Me he encontrado con esto:

item = someSortOfSelection()
if item in myList:
    doMySpecialFunction(item)

Pero a veces no funciona con todos mis elementos, como si no fueran reconocidos en la lista (cuando es una lista de cadenas).

¿Es esta la forma más 'pitónica' de encontrar un elemento en una lista: if x in l:?

 389
Author: Engineero, 2012-03-03

9 answers

En cuanto a su primera pregunta: ese código está perfectamente bien y debería funcionar si item es igual a uno de los elementos dentro de myList. Tal vez intenta encontrar una cadena que no exactamente coincide con uno de los elementos o tal vez está utilizando un valor flotante que sufre de inexactitud.

En cuanto a su segunda pregunta: En realidad hay varias maneras posibles si "encontrar" cosas en las listas.

Comprobando si hay algo dentro

Este es el caso de uso que describe: Comprobación si algo está dentro de una lista o no. Como sabes, puedes usar el operador in para eso:

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

Filtrar una colección

Es decir, encontrar todos los elementos en una secuencia que cumplen una determinada condición. Puedes usar expresiones de comprensión de listas o 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 se puede imaginar como una especie de lista perezosa que solo se construirá tan pronto como se itere a través de ella. Por cierto, la primera 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, filter no devuelve una lista, sino un objeto similar a un generador.

Encontrando la primera ocurrencia

Si solo desea la primera cosa que coincida con una condición (pero aún no sabe cuál es), está bien usar un bucle for (posiblemente usando la cláusula else también, que no es muy conocida). También puede utilizar

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

Que devolverá la primera igualar o subir un StopIteration si no se encuentra ninguno. Alternativamente, puede usar

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

Encontrar la ubicación de un elemento

Para las listas, también está el método index que a veces puede ser útil si desea saber dónde se encuentra un cierto 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, .index siempre devuelve el índice más bajo:......

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

Si hay duplicados y desea todos los índices, puede usar {[16]]} lugar:

[i for i,x in enumerate([1,2,3,2]) if x==2] # => [1, 3]
 841
Author: Niklas B.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-12-14 16:21:34

Si desea encontrar un elemento o None utilizar por defecto en next, no se levantará StopIteration si el elemento no se encontró en la lista:

first_or_default = next((x for x in lst if ...), None)
 128
Author: Janusz Skonieczny,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-04-24 17:22:44

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

next((i for i, x in enumerate(lst) if [condition on x]), [default value])
 14
Author: Vincent,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-12-04 06:53:16

Encontrando 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  
 4
Author: Antony Hatchkins,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-01-07 19:07:17

Otra alternativa: puede verificar si un elemento está en una lista con if item in list:, pero este es el orden O(n). Si está tratando con grandes listas de elementos y todo lo que necesita saber es si algo es miembro de su lista, puede convertir la lista a un conjunto primero y aprovechar constant time set lookup :

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

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

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

 1
Author: Engineero,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-09-08 20:42:34

Compruebe que no hay espacios blancos adicionales/no deseados en los elementos de la lista de cadenas. Esa es una razón que puede estar interfiriendo explicando que los artículos no se pueden encontrar.

 0
Author: Stephane Rolland,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-07-05 08:02:26

Es posible que desee utilizar una de las dos búsquedas posibles mientras trabaja con la lista de cadenas:

  1. Si el elemento list es igual a un elemento ('ejemplo' está en ['uno','ejemplo','dos']):

    if item in your_list: some_function_on_true()

    'ex' in ['one','ex','two'] = > True

    'ex_1' in ['one','ex','two'] = > False

  2. Si el elemento list es como un elemento ('ex' está en ['uno,'ejemplo','dos'] o 'example_1' es en ['uno','ejemplo','dos']):

    matches = [el for el in your_list if item in el]

    O

    matches = [el for el in your_list if el in item]

    Luego simplemente marque len(matches) o léalos si es necesario.

 0
Author: Alexey Antonenko,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-01-23 08:49:06
list = [10, 20, 30, 40, 50]
n = int(input("\nEnter a Number to search from the list : "))

if n in list :
    print("\nMatch found")  
else :
    print("\nMatch not found")
 0
Author: Rekha V,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-08-02 05:38:59

Por ejemplo, si desea encontrar el índice de todos los elementos mayores que 30:

your_list = [11,22,23,44,55]
filter(lambda x:your_list[x]>30,range(len(your_list)))

#result: [3,4]
 -2
Author: Statham,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-04-10 01:38:17