2010-07-17 11 views
81

posso fare cosa del genere in pitone:Controllare elenco di parole in un'altra stringa

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

Questo controllerà se 'una parola' esiste nella lista. Ma posso fare qualcosa inverso?

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

devo controllare se alcune parole di matrice sono nella stringa. Posso farlo usando il ciclo ma in questo modo ho più linee di codice.

+6

Utilizzando "lista" come un nome di variabile ti porterà nei guai, come nasconde la "lista" python –

+0

@Fabian, sì, certo. È solo per esempio. – Ockonal

+0

È preferibile preferire la lettura al numero di righe di codice. In questo caso "any" è perfetto, ma a volte usare più linee è meglio di un solo liner –

risposta

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

@Ockonal: e se vuoi controllare che ** tutte le parole ** di quella lista siano all'interno della stringa, basta sostituire ' any() 'precedente con' all() ' –

+13

Nota che se 'me' è in' list_', verrà conteggiato come una corrispondenza, poiché 'me' è in 'alcuni'. Se vuoi abbinare solo parole intere, devi passare a 'any (parola in 'some one long two phrase three.split() per word in list_)', come ho fatto durante la creazione degli insiemi nella mia risposta . – PaulMcG

+0

@NasBanov cosa devo fare se voglio contare il numero di corrispondenze tra la lista e la stringa? –

12

Qui ci sono un paio di modi alternativi di farlo, che possono essere più veloce o più adatto di risposta di KennyTM, a seconda del contesto.

1) usare un'espressione regolare:

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) Si potrebbe usare set se si desidera far corrispondere le parole intere, per esempio non si vuole trovare la parola "il" nella frase "li teoremi sono teorica":

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

Naturalmente si può anche fare parola intera partite con espressioni regolari usando il token "\ b".

Le prestazioni di queste e della soluzione di Kenny dipendono da diversi fattori, ad esempio la lunghezza dell'elenco di parole e della stringa di frasi e la frequenza con cui cambiano. Se le prestazioni non sono un problema, andate per il più semplice, che è probabilmente quello di Kenny.

+0

Grazie per tale risposta. E, per favore, aggiungi la citazione dopo 'list_of_words' alla seconda riga. – Ockonal

+0

ho appena provato l'ultimo in python 3.3 Ho dovuto usare 'if word_set.intersection (phrase_set):' – user3271518

+0

@dave che è un modo più efficiente se il mio elenco di parole sarà lungo 30-50 parole e le mie stringhe sarà fino a 300 parole. E devo fare più di 100k confronti simili? – ketanbhatt

15

Se il tuo elenco di parole ha una lunghezza considerevole e devi eseguire questo test molte volte, può valere la pena convertire l'elenco in un set e utilizzare l'intersezione impostata per testare (con l'ulteriore vantaggio che otterrai parole reali che si trovano in entrambe le liste):

>>> 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

Quello non sarà lo stesso come controlla solo se le parole separate da spazi corrispondono alle parole che stai cercando. Ad esempio, non sarà possibile trovare 'foo' all'interno di' foobar'. – poke

+0

@poke - Vero. Non mi è chiaro se l'OP vuole corrispondenze di parole parziali/incorporate o meno. Il più delle volte, le persone scrivono il test del codice per una parola all'interno di una stringa di parole più ampia, supponendo che stiano facendo la corrispondenza delle parole, ma di fatto stanno facendo la corrispondenza delle stringhe. Questo metodo controlla le parole intere contro un insieme di parole intere, senza cercare corrispondenze incorporate (come ad esempio "out" in "about"). – PaulMcG

+0

Sì, certo, ho pensato che potrebbe essere importante menzionare che la tua soluzione (che è una buona btw.) Non si comporta allo stesso modo dell'operatore 'in'. – poke

1

facile e più semplice metodo per risolvere questo problema è usando 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 
Problemi correlati