Вот мой подход к поиску подстрок в списке, содержащем «фразы», путем поиска по списку, содержащему «слова», и возврата соответствующих подстрок, которые были найдены в каждом элементе в списке, содержащем фразы.
import re
def is_phrase_in(phrase, text):
return re.search(r"\b{}\b".format(phrase), text, re.IGNORECASE) is not None
list_to_search = ['my', 'name', 'is', 'you', 'your']
list_to_be_searched = ['hello my', 'name is', 'john doe doe is last name', 'how are you', 'what is your name', 'my name is jane doe']
to_be_appended = []
for phrase in list_to_be_searched:
searched = []
for word in list_to_search:
if is_phrase_in(word,phrase) is True:
searched.append(word)
to_be_appended.append(searched)
print(to_be_appended)
# (desired and actual) output
[['my'],
['name', 'is'],
['name', 'is'],
['you'],
['name', 'is', 'your'],
['my', 'name', 'is']]
Поскольку список «words» (или list_to_search) содержит ~ 1700 слов, а список «phrases» (или list_to_be_searched) - ~ 26561, завершение кода занимает более 30 минут.Я не думаю, что мой код выше был реализован с учетом Pythonic способа кодирования и эффективной структуры данных.: (
Может кто-нибудь дать какой-нибудь совет по оптимизации или сделать это быстрее?
Спасибо!
На самом деле, я написал неправильный пример выше. Что если 'list_to_search' имеетэлементы с более чем 2 словами?
import re
def is_phrase_in(phrase, text):
return re.search(r"\b{}\b".format(phrase), text, re.IGNORECASE) is not None
list_to_search = ['hello my', 'name', 'is', 'is your name', 'your']
list_to_be_searched = ['hello my', 'name is', 'john doe doe is last name', 'how are you', 'what is your name', 'my name is jane doe']
to_be_appended = []
for phrase in list_to_be_searched:
searched = []
for word in list_to_search:
if is_phrase_in(word,phrase) is True:
searched.append(word)
to_be_appended.append(searched)
print(to_be_appended)
# (desired and actual) output
[['hello my'],
['name', 'is'],
['name', 'is'],
[],
['name', 'is', 'is your name', 'your'],
['name', 'is']]
Синхронизация 1-й метод:
%%timeit
def is_phrase_in(phrase, text):
return re.search(r"\b{}\b".format(phrase), text, re.IGNORECASE) is not None
list_to_search = ['hello my', 'name', 'is', 'is your name', 'your']
list_to_be_searched = ['hello my', 'name is', 'john doe doe is last name', 'how are you', 'what is your name', 'my name is jane doe']
to_be_appended = []
for phrase in list_to_be_searched:
searched = []
for word in list_to_search:
if is_phrase_in(word,phrase) is True:
searched.append(word)
to_be_appended.append(searched)
#43.2 µs ± 346 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
2-й метод (понимание вложенного списка и re.findall)
%%timeit
[[j for j in list_to_search if j in re.findall(r"\b{}\b".format(j), i)] for i in list_to_be_searched]
#40.3 µs ± 454 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)\
Срокиопределенно улучшилось, но будет ли более быстрый путь? Или, задача генетически медленная, учитывая, что она делает?