2010-07-17 14 views
81

que pueda hacer tal cosa en Python:Comprobar lista de palabras en otra cadena

l = ['one', 'two', 'three'] 
if 'some word' in l: 
    ... 

Este comprobará si existe "alguna palabra en la lista. ¿Pero puedo hacer lo contrario?

l = ['one', 'two', 'three'] 
if l in 'some one long two phrase three': 
    ... 

Tengo que comprobar si algunas palabras de la matriz están en la cadena. Puedo hacer esto usando un ciclo, pero de esta manera tengo más líneas de código.

+6

el uso de "lista" como nombre de variable se meterte en problemas, como oculta la "lista" de Python –

+0

@Fabian, sí, claro. Es solo por muestra. – Ockonal

+0

Es mejor preferir la legibilidad sobre el número de líneas de código. En este caso 'any' es un ajuste perfecto, pero a veces usar más líneas es mejor que un liner –

Respuesta

194
if any(word in 'some one long two phrase three' for word in list_): 
+13

@Ockonal: y si quiere verificar que ** todas ** palabras de esa lista están dentro de la cadena, simplemente reemplace' any() 'arriba con' all() ' –

+13

Tenga en cuenta que si 'me' está en' list_', contará como una coincidencia, ya que 'me' está en 'some'. Si quieres unir palabras completas solamente, necesitarás cambiar a 'any (palabra en 'alguna palabra larga dos frases' tres '.split() para palabra en lista_)', como lo hice al crear los conjuntos en mi respuesta . – PaulMcG

+0

@NasBanov ¿qué debo hacer si quiero contar el número de coincidencias entre la lista y la cadena? –

12

Aquí hay un par de formas alternativas de hacerlo, que pueden ser más rápido o más conveniente que la respuesta de KennyTM, dependiendo del contexto.

1) utiliza una expresión regular:

import re 
words_re = re.compile("|".join(list_of_words)) 

if words_re.search('some one long two phrase three'): 
    # do logic you want to perform 

2) Se podría utilizar conjuntos si desea hacer coincidir palabras completas, por ejemplo usted no quiere encontrar la palabra "the" en la frase "los teoremas son teóricos":

word_set = set(list_of_words) 
phrase_set = set('some one long two phrase three'.split()) 
if word_set.intersection(phrase_set): 
    # do stuff 

Por supuesto, también puede hacer toda la palabra partidos con expresiones regulares utilizando el token "\ b".

El rendimiento de estas y la solución de Kenny dependerán de varios factores, como por ejemplo, cuánto tiempo son la lista de palabras y la cadena de frases, y con qué frecuencia cambian. Si el rendimiento no es un problema, entonces elija el más simple, que probablemente sea el de Kenny.

+0

Gracias por tal respuesta. Y, por favor, agregue comillas después de 'list_of_words' en la segunda línea. – Ockonal

+0

acaba de probar el último en Python 3.3 Tenía que usar 'if word_set.intersection (phrase_set):' – user3271518

+0

@dave, que es una manera más eficiente si mi lista de palabras va a ser de 30-50 palabras de largo, y mis cadenas será hasta 300 palabras. ¿Y tengo que hacer más de 100.000 comparaciones? – ketanbhatt

15

Si su lista de palabras es de longitud considerable, y necesita hacer esta prueba muchas veces, puede valer la pena convertir la lista a un conjunto y usar la intersección de conjuntos para probar (con el beneficio adicional de que obtendrá el palabras reales que se encuentran en ambas listas):

>>> long_word_list = 'some one long two phrase three about above along after against' 
>>> long_word_set = set(long_word_list.split()) 
>>> set('word along river'.split()) & long_word_set 
set(['along']) 
+0

Eso no será lo mismo ya que solo verifica si las palabras separadas por espacios coinciden con las palabras que está buscando. Por ejemplo, no podrá encontrar 'foo' en' foobar'. – poke

+0

@poke - cierto. No me queda claro si el OP quiere que coincida o no la palabra parcial/incrustada. Con la misma frecuencia, las personas escriben pruebas de código para una palabra dentro de una cadena de palabras más grande, asumiendo que están haciendo una coincidencia de palabras, pero de hecho están haciendo una coincidencia de cadenas. Este método comprueba las palabras completas contra un conjunto de palabras completas, sin buscar coincidencias incrustadas (como la coincidencia de 'salir' en 'sobre'). – PaulMcG

+0

Sí, claro, pensé que podría ser importante mencionar que su solución (que es buena por cierto) no se comporta igual que el operador 'in'. – poke

1

método más fácil y sencilla de resolver este problema es utilizando re

import re 

search_list = ['one', 'two', 'there'] 
long_string = 'some one long two phrase three' 
if re.compile('|'.join(search_list),re.IGNORECASE).search(long_string): #re.IGNORECASE is used to ignore case 
    # Do Something if word is present 
else: 
    # Do Something else if word is not present 
Cuestiones relacionadas