2010-08-18 10 views
9

Disculpe si la pregunta es un poco confusa. Esto es similar a this questionCómo eliminar la lista de palabras de una lista de cadenas

Creo que esta pregunta está cerca de lo que quiero, pero en Clojure.

Hay another pregunta

necesito algo como esto, pero en lugar de '[sa]' en esa pregunta, hay una lista de cadenas que necesitan ser buscado y eliminado.

Espero haber sido claro.

Creo que esto se debe a que las cadenas en python son inmutables.

Tengo una lista de palabras irrelevantes que deben eliminarse de una lista de cadenas.

Si utilizo la lista de comprensión, termino buscando la misma cadena una y otra vez. Por lo tanto, solo "de" se elimina y no "el". Así que mi lista modificada se parece a esto

places = ['New York', 'the New York City', 'at Moscow' and many more] 

noise_words_list = ['of', 'the', 'in', 'for', 'at'] 

for place in places: 
    stuff = [place.replace(w, "").strip() for w in noise_words_list if place.startswith(w)] 

me gustaría saber en cuanto a lo que estoy haciendo error.

+1

¿Cuál es 'place'? – katrielalex

+0

No te estás dejando claro; diga su pregunta * aquí *, y luego ponga enlaces a preguntas similares con respuestas similares si cree que es necesario a continuación. –

Respuesta

9

Aquí está mi puñalada. Esto usa expresiones regulares.

import re 
pattern = re.compile("(of|the|in|for|at)\W", re.I) 
phrases = ['of New York', 'of the New York'] 
map(lambda phrase: pattern.sub("", phrase), phrases) # ['New York', 'New York'] 

Sans lambda:

[pattern.sub("", phrase) for phrase in phrases] 

Actualizar

Arreglo para el error señalado por gnibbler (gracias!):

pattern = re.compile("\\b(of|the|in|for|at)\\W", re.I) 
phrases = ['of New York', 'of the New York', 'Spain has rain'] 
[pattern.sub("", phrase) for phrase in phrases] # ['New York', 'New York', 'Spain has rain'] 

@prabhu: el cambio anterior evita cortar el trailing "en "de" España ". Para verificar ejecutar ambas versiones de las expresiones regulares contra la frase "España tiene lluvia".

+0

Gracias. Funciona de esta manera. Pude entender el concepto de lambda con mayor claridad ahora que tuve la oportunidad de implementar esto. – prabhu

+1

Esto no funciona correctamente para la frase "España tiene lluvia". Sin embargo, es fácil de arreglar –

+0

@Gnibbler: gracias por señalarlo. Estoy cambiando mi respuesta en consecuencia. –

3
>>> import re 
>>> noise_words_list = ['of', 'the', 'in', 'for', 'at'] 
>>> phrases = ['of New York', 'of the New York'] 
>>> noise_re = re.compile('\\b(%s)\\W'%('|'.join(map(re.escape,noise_words_list))),re.I) 
>>> [noise_re.sub('',p) for p in phrases] 
['New York', 'New York'] 
+0

¡Guau! Esa es una forma genial de hacer, aunque forcé mi cerebro. :-) – prabhu

+0

Esto no parece obtener cada instancia de palabras. Por ejemplo, "de Nueva York de" se convierte en "Nueva York de". – Namey

+1

@Namey, podrías usar algo como ''\\ W? \\ b (% s) \\ W?''. Sin el OP que proporciona un conjunto completo de testcases, es un poco como un golpe –

1

Desde que le gustaría saber lo que está haciendo mal, esta línea:

stuff = [place.replace(w, "").strip() for w in noise_words_list if place.startswith(w)] 

tiene lugar, y luego comienza a reproducir indefinidamente palabras. Primero comprueba "de". Se verifica su lugar (por ejemplo, "de Nueva York") para ver si comienza con "de". Se transforma (llamada para reemplazar y quitar) y se agrega a la lista de resultados. Lo crucial aquí es que el resultado nunca se examina de nuevo. Por cada palabra que itere en la comprensión, se agrega un nuevo resultado a la lista de resultados. Entonces, la siguiente palabra es "the" y su lugar ("of the New York") no comienza con "the", por lo que no se agrega ningún resultado nuevo.

Supongo que el resultado que obtuvo finalmente es la concatenación de las variables de su lugar. Un sencillo de leer y entender la versión del procedimiento fuera (no probado):

results = [] 
for place in places: 
    for word in words: 
     if place.startswith(word): 
      place = place.replace(word, "").strip() 
    results.append(place) 

Tenga en cuenta que replace() eliminará la palabra en cualquier lugar de la cadena, incluso si se produce como un simple subcadena. Puede evitar esto usando expresiones regulares con un patrón algo así como ^the\b.

+0

Gracias. Eso fue muy útil. – prabhu

14

Sin expresión regular que podría hacer la siguiente manera:

places = ['of New York', 'of the New York'] 

noise_words_set = {'of', 'the', 'at', 'for', 'in'} 
stuff = [' '.join(w for w in place.split() if w.lower() not in noise_words_set) 
     for place in places 
     ] 
print stuff 
+0

¡Excelente! ¡Gracias! – prabhu

+0

Me encontré con esto y no tenía idea de lo que está pasando aquí. Si alguien tropieza con esto y se pregunta qué magia está sucediendo, se llama lista de comprensión y este es un buen artículo que lo explica http://carlgroner.me/Python/2011/11/09/An-Introduction-to-List-Comprehensions- in-Python.html –

Cuestiones relacionadas