2015-01-05 2 views
4

У меня есть приложение Python.Самый быстрый способ проверить, содержит ли строка любое слово из списка

Существует список 450 запрещенных фраз. От пользователя получено сообщение. Я хочу проверить, содержит ли это сообщение какие-либо из этих запрещенных фаразий. Каков самый быстрый способ сделать это?

В настоящее время у меня есть этот код:

message = "sometext" 
lista = ["a","b","c"] 

isContaining = false 

for a, member in enumerate(lista): 
if message.contains(lista[a]): 
    isContaining = true 
    break 

Есть ли более быстрый способ сделать это? Мне нужно обрабатывать сообщение (максимум 500 символов) менее чем за 1 секунду.

+0

'isContaining = любой (х в сообщении для й в) Листе' – falsetru

+1

Прежде всего, удалить '' enumerate' и а, 'части , Замените 'lista [a]' на 'member'. Во-вторых, функция 'in' не быстрее? Итак, что-то вроде 'if member in message:' – Mathias711

+1

Тестирование членства происходит быстрее на [a 'set'] (https://docs.python.org/2/library/stdtypes.html#set-types-set-frozenset). – jonrsharpe

ответ

8

Существует встроенная функция any специально для этого:

>>> message = "sometext" 
>>> lista = ["a","b","c"] 
>>> any(a in message for a in lista) 
False 
>>> lista = ["a","b","e"] 
>>> any(a in message for a in lista) 
True 

В качестве альтернативы вы можете проверить пересечение множеств:

>>> lista = ["a","b","c"] 
>>> set(message) & set(lista) 
set([]) 
>>> lista = ["a","b","e"] 
>>> set(message) & set(lista) 
set(['e']) 
>>> set(['test','sentence'])&set(['this','is','my','sentence']) 
set(['sentence']) 

Но вы не сможете для проверки подзаголовков:

>>> set(['test','sentence'])&set(['this is my sentence']) 
+0

Спасибо, я буду использовать и принять ваш ответ! – TN888

+0

Кроме того, сортируйте слова в списке, чтобы первые были первыми (я предполагаю, что они имеют наибольшую вероятность появления в сообщении). – RemcoGerlich

+1

set (message) не будет работать, если он ищет слова, а не символы. – RemcoGerlich

1

Я бы совместить any встроенную команду с оператором in:

isContaining = any(a in message for a in lista) 

Я не знаю, если это самый быстрый способ, но это, кажется, самый простой для меня.

3

Использование regex compile from list

Рассмотрим память и время здание или выражение, компилировать заранее.

lista = [...] 
lista_escaped = [re.escape(item) for item in lista] 
bad_match = re.compile('|'.join(lista_escaped)) 
is_bad = bad_match.search(message, re.IGNORECASE) 
+3

Объединить с re.escape() для поиска фиксированной строки. re.compile создаст аккуратно оптимизированный конечный автомат для сканирования строк. –

0

Мы можем также использовать метод setintersection

>>> message = "sometext" 
>>> lista = ["a","b","c"] 
>>> isContaining = False 
>>> if set(list(message)).intersection(set(lista)): 
... isContaining = True 
... 
>>> isContaining 
False 
>>> message = "sometext a" 
>>> list(message) 
['s', 'o', 'm', 'e', 't', 'e', 'x', 't', ' ', 'a'] 
>>> if set(list(message)).intersection(set(lista)): 
... isContaining = True 
... 
>>> isContaining 
True 
+1

Это работает только для односимвольных фраз. – RemcoGerlich

+0

да, мне нужно создать список всех комбинаций строки 'message'. –

Смежные вопросы