Compruebe si un elemento de la lista de Python contiene una cadena dentro de otra cadena


588

Tengo una lista:

my_list = ['abc-123', 'def-456', 'ghi-789', 'abc-456']

y desea buscar elementos que contengan la cadena 'abc'. ¿Cómo puedo hacer eso?

if 'abc' in my_list:

comprobaría si 'abc'existe en la lista pero es parte de 'abc-123'y 'abc-456', 'abc'no existe por sí solo. Entonces, ¿cómo puedo obtener todos los artículos que contienen 'abc'?


19
Para verificar lo contrario (si una cadena contiene una entre varias cadenas): stackoverflow.com/a/6531704/2436175
Antonio

Si las partes izquierdas de las entradas son únicas, considere construir un dict de la lista: Encuentre una entrada en una lista basada en una cadena parcial
Georgy

Respuestas:


931

Si solo desea verificar la presencia de abccualquier cadena en la lista, puede intentar

some_list = ['abc-123', 'def-456', 'ghi-789', 'abc-456']
if any("abc" in s for s in some_list):
    # whatever

Si realmente desea obtener todos los elementos que contienen abc, use

matching = [s for s in some_list if "abc" in s]

Tengo que verificar si un elemento está en una matriz de 6 elementos. ¿Es más rápido hacer 6 "si" o es lo mismo?
Olivier Pons

42
@OlivierPons, solo hazloif myitem in myarray:
alldayremix

8
Otra forma de obtener todas las cadenas que contienen la subcadena 'abc':filter(lambda element: 'abc' in element, some_list)
driftcatcher

2
@ p014k: use el index()método:try: return mylist.index(myitem); except ValueError: pass
Sven Marnach

1
@midkin: No entiendo exactamente qué estabas tratando de hacer, ni cómo salió mal. Probablemente tenga más suerte haciendo una nueva pregunta (con el botón "Preguntar"), copiando su código exacto, lo que esperaba que hiciera el código y lo que realmente hizo. "No funcionó" no tiene ningún sentido a menos que defina lo que "funciona" en este contexto, pero aun así es mejor explicar lo que realmente sucedió en lugar de decir lo que no.
Sven Marnach

104

Simplemente lanzando esto por ahí: si necesita hacer coincidir más de una cadena, por ejemplo , abcy defpuede combinar dos comprensiones de la siguiente manera:

matchers = ['abc','def']
matching = [s for s in my_list if any(xs in s for xs in matchers)]

Salida:

['abc-123', 'def-456', 'abc-456']

44
Esto era exactamente lo que estaba buscando en Google ... ¡Gracias!
N8TRO

2
También puede usar {s for s in my_list for xs in matchers if xs in s}(tenga en cuenta las llaves para crear un conjunto único). Puede ser más fácil de leer, pero podría ser más lento si la mayoría de los svalores tienen una coincidencia, ya que anyse detendrá eficientemente en la primera coincidencia.
Matthias Fripp

82

Use filterpara llegar a los elementos que tienen abc.

>>> lst = ['abc-123', 'def-456', 'ghi-789', 'abc-456']
>>> print filter(lambda x: 'abc' in x, lst)
['abc-123', 'abc-456']

También puedes usar una lista de comprensión.

>>> [x for x in lst if 'abc' in x]

Por cierto, no use la palabra listcomo nombre de variable ya que ya se usa para el listtipo.


50

Si solo necesita saber si 'abc' está en uno de los elementos, esta es la forma más corta:

if 'abc' in str(my_list):

1
Esto fallaría si tuviera una lista de ["abc1", "1abc2"] ya que encontraría una coincidencia porque la cadena 'abc' estaría en la cadena recién creada
cgseller

2
Sí, este es el comportamiento previsto ... cierto si alguno de los elementos contiene 'abc'
RogerS

77
¡No sé por qué todas estas otras personas deciden hacer esas complicadas soluciones lambda cuando no lo necesitan! Buen trabajo @RogerS
ntk4

1
En realidad, la misma pregunta casi se responde sola ... Acabo de agregarle 3 letras.
RogerS

1
Es una buena solución, pero si desea encontrar los elementos que contienen la cadena dada, no tendrá éxito. Aquí descubrirá si alguno de los elementos contiene la cadena.
cslotty

18

Esta es una pregunta bastante antigua, pero ofrezco esta respuesta porque las respuestas anteriores no hacen frente a elementos en la lista que no son cadenas (o algún tipo de objeto iterable). Dichos elementos causarían que toda la comprensión de la lista falle con una excepción.

Para tratar con gracia dichos elementos en la lista omitiendo los elementos no iterables, utilice lo siguiente:

[el for el in lst if isinstance(el, collections.Iterable) and (st in el)]

entonces, con tal lista:

lst = [None, 'abc-123', 'def-456', 'ghi-789', 'abc-456', 123]
st = 'abc'

aún obtendrá los elementos coincidentes ( ['abc-123', 'abc-456'])

La prueba de iterable puede no ser la mejor. Lo tengo desde aquí: en Python, ¿cómo puedo determinar si un objeto es iterable?


¿No [el for el in lst if el and (st in el)]tendría más sentido en el ejemplo dado?
Gordo

@tinix No, eso manejará objetos no iterables con gracia, ¿verdad?
Robert Muil

"ejemplo dado" my_list = ['abc-123', 'def-456', 'ghi-789', 'abc-456'] no hay necesidad de complicarlo demasiado.
Gordo

1
Sí, absolutamente, la respuesta aceptada es perfectamente adecuada y mi sugerencia es más complicada, así que siéntase libre de ignorarla. Solo ofrecí en caso de que alguien tuviera el mismo problema que yo: los elementos no iterables en tales listas son una posibilidad del mundo real. a pesar de no existir en el ejemplo dado.
Robert Muil

13
x = 'aaa'
L = ['aaa-12', 'bbbaaa', 'cccaa']
res = [y for y in L if x in y]

10
for item in my_list:
    if item.find("abc") != -1:
        print item

3
Si va a adoptar este enfoque, creo que es más idiomático hacerlo if 'abc' in itemque usarlo item.find('abc') == -1.
Wyatt Baldwin


4

Utilice el __contains__()método de la clase de cadena Pythons .:

a = ['abc-123', 'def-456', 'ghi-789', 'abc-456']
for i in a:
    if i.__contains__("abc") :
        print(i, " is containing")

3

Soy nuevo en Python. Obtuve el siguiente código funcionando y lo hice fácil de entender:

my_list = ['abc-123', 'def-456', 'ghi-789', 'abc-456']
for str in my_list:
    if 'abc' in str:
       print(str)

0
my_list = ['abc-123', 'def-456', 'ghi-789', 'abc-456']

for item in my_list:
    if (item.find('abc')) != -1:
        print ('Found at ', item)

0
mylist=['abc','def','ghi','abc']

pattern=re.compile(r'abc') 

pattern.findall(mylist)

En Python3.6 esto da un error: TypeError: cadena esperada u objeto similar a bytes
AimForClarity

1
@AimForClarity Sí. re.findall en python3.6 espera una cadena. Una alternativa sería convertir la lista en una cadena import re mylist=['abc','def','ghi','abcff'] my_list_string=''.join(mylist) string_to_find="abc" res=re.findall(string_to_find,my_list_string) print(res)
arun_munagala

1
Perdón por el mal formato. No se pudieron hacer saltos de línea adecuados por alguna razón.
arun_munagala

0

Hice una búsqueda, que requiere que ingrese un cierto valor, luego buscará un valor de la lista que contiene su entrada:

my_list = ['abc-123',
        'def-456',
        'ghi-789',
        'abc-456'
        ]

imp = raw_input('Search item: ')

for items in my_list:
    val = items
    if any(imp in val for items in my_list):
        print(items)

Intenta buscar 'abc'.


0
def find_dog(new_ls):
    splt = new_ls.split()
    if 'dog' in splt:
        print("True")
    else:
        print('False')


find_dog("Is there a dog here?")

0

Necesitaba los índices de la lista que corresponden a una coincidencia de la siguiente manera:

lst=['abc-123', 'def-456', 'ghi-789', 'abc-456']

[n for n, x in enumerate(lst) if 'abc' in x]

salida

[0, 3]

-1

Pregunta: Proporcione la información de abc

    a = ['abc-123', 'def-456', 'ghi-789', 'abc-456']


    aa = [ string for string in a if  "abc" in string]
    print(aa)

Output =>  ['abc-123', 'abc-456']

-2

Que yo sepa, una declaración 'para' siempre consumirá tiempo.

Cuando la longitud de la lista aumenta, el tiempo de ejecución también aumentará.

Creo que buscar una subcadena en una cadena con la instrucción 'es' es un poco más rápido.

In [1]: t = ["abc_%s" % number for number in range(10000)]

In [2]: %timeit any("9999" in string for string in t)
1000 loops, best of 3: 420 µs per loop

In [3]: %timeit "9999" in ",".join(t)
10000 loops, best of 3: 103 µs per loop

Pero, estoy de acuerdo en que la anydeclaración es más legible.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.