我有一个长(1.5米)的句子列表和一个类似的长词列表,我在句子列表中寻找。例如:
list_of_words = ['Turin', 'Milan']
list_of_sents = ['This is a sent about turin.', 'This is a sent about manufacturing.']
我希望有一个函数能够返回那些包含目标字的句子,旁边没有字母数字字符。换句话说,只有上面第一个句子匹配。
我已经开发了下面的函数,但是解析每个数百万个单词和句子需要很长时间。我想知道是否有一个包或替代品可以减轻这种计算强度。
def find_target_sents(list_of_words, list_of_sents):
target_sents = []
i, j = 0, 0
word_len = len(list_of_words)
sent_len = len(list_of_sents)
for word in list_of_words:
i += 1
for sent in list_of_sents:
j += 1
print('%s out of %s words and %s out of %s sentences' % (j, word_len , i, sent_len))
match = re.compile(r'\%s\b' % word, re.I)
y = match.search(sent)
if y != None:
print(sent)
t = (word, sentence)
target_sent.append(t)
print(target_sent)
答案 0 :(得分:1)
如果您可以构建一个字符串,其中包含要从list_of_words搜索的所有字词,例如deleteOne
,你可以做一个正则表达式匹配:
(Turin|Milan)
此外,我们可以避免使用for循环,如answer中所述。
答案 1 :(得分:0)
可以构建集合并使用其常量时间成员资格检查:
from string import punctuation
def find_target_sents(words, sents):
# translation table
table = str.maketrans('', '', punctuation)
# hold found sentences by word
found = {word: [] for word in words}
# make unique sets for each sentence and remove punctuation
parsed = [set(sent.translate(table).split()) for sent in sents]
# check
for word in found:
for sent in parsed:
if word in sent:
found[word].append(sent)
基本上,这假设你的句子遵循英语语法,并且在字符或功能之后用空格分隔(假设当然会有另一个单词)。
它接受每个句子并从中删除任何标点符号,然后在空格上拆分并将结果转换为set
,其具有恒定时间,O(1),成员资格检查。
所以句子:"I, want to go, to Burger King!"
......
...变为('I', 'want', 'to', 'go', 'Burger', 'King')
;只存在独特元素的地方!
显然,如果你正在寻找'Burger King'
会有问题但技术上只有两个字......