Вы должны использовать наборы, которые намного быстрее, чем списки и полнотекстовый поиск при поиске предметов.
Поместите эти понятия в набор множеств, проиндексированных по количеству слов. Затем разбейте inputString
на список слов, а затем используйте скользящее окно количества слов в этом списке, чтобы проверить, существуют ли эти слова в наборе индекса того же количества слов.
Итак, при следующей инициализации:
from collections import defaultdict
import re
inputString = "The cow is a domestic animal. It has four legs, one tail, two eyes"
concepts = ["cow", "domestic animal", "domestic bird", "forever and ever", "practice makes perfect", "i will be back"]
Разобьем concepts
на части наборов, проиндексированных по количеству слов понятий, содержащихся в наборе:
concept_sets = defaultdict(set)
for concept in concepts:
concept_sets[len(concept.split())].add(concept)
Так что concept_sets
становится:
{1: {'cow'}, 2: {'domestic bird', 'domestic animal'}, 3: {'practice makes perfect', "forever and ever"}, 4: {'i will be back'}}
Затем мы превращаем inputString
в список слов в нижнем регистре, чтобы совпадение не зависело от регистра. Обратите внимание, что вы можете уточнить здесь регулярное выражение, чтобы оно могло включать некоторые другие символы в качестве «слова».
input_words = list(map(str.lower, re.findall(r'[a-z]+', inputString, re.IGNORECASE)))
Наконец, мы перебираем каждый набор понятий в concept_sets
с его количеством слов, просматриваем список слов из ввода в скользящем окне с таким же количеством слов и проверяем, существуют ли слова в наборе .
for num_words, concept_set in concept_sets.items():
for i in range(len(input_words) - num_words + 1):
words = ' '.join(input_words[i: i + num_words])
if words in concept_set:
print("found '%s' in '%s'" % (words, inputString))
Это выводит:
found 'cow' in 'The cow is a domestic animal. It has four legs, one tail, two eyes'
found 'domestic animal' in 'The cow is a domestic animal. It has four legs, one tail, two eyes'