Python 字符串匹配 - 查找一个单词列表中一定数量的单词是否存在于另一个列表中的一个句子中

Python string matching - Find if certain number of words in a list of words exist in a sentence in another list

我有一个字符串和一个列表,定义如下

my_string = 'she said he replied'
my_list = ['This is a cool sentence', 'This is another sentence','she said hello he replied goodbye', 'she replied', 'Some more sentences in here', 'et cetera et cetera...']

我正在尝试检查 my_string 中的至少 3 个单词是否存在于 my_list 中的任何字符串中。我采用的方法是拆分my_string,然后使用all进行匹配。但是,这仅在 my_string 中的所有项目都存在于 my_list

的句子中时才有效
if all(word in item for item in my_list for word in my_string.split()):
    print('we happy')

1- 如果句子列表中存在至少 3 个 my_string 项,我怎样才能满足条件?

2- 是否可以只匹配 my_string 中的第一个和最后一个单词以相同的顺序?即 "she" 和 "replied" 出现在 'she replied' 中 my_list 的索引 3,return True.

使用True为1,False为0的固有编码。 in 个结果的总和:

if sum(word in item for item in my_list for word in my_string.split()) >= 3:
    print('we happy')

对于您给定的输入,这将打印 we happy

回复:mamun的观点,我们也想确保整个单词匹配。您需要拆分 my_list 中的每个字符串以获取可用单词列表。 kaya3 已经发布了我要您做的事情。

可以使用集合交集计算两个字符串之间的共同词。结果集的 len 给出了字符串共有的单词数。

首先使用集合并集

构建my_list中字符串中所有单词的集合:

all_words = set.union(*[set(item.split()) for item in my_list])

然后检查交集是否有长度>= 3:

search_words = set(my_string.split())
if len(search_words & all_words) >= 3:
    print('we happy')

关于第 1 部分,我认为这应该可行,我建议使用正则表达式而不是 string.split 来查找 words.You 如果您的句子包含复杂的单词,也可以使用 nltk.word_tokenize和标点符号。它们都比 string.split 慢,但如果您需要它们,它们很有用。

这里有几篇不错的帖子强调了差异(wordpunct-tokenize 基本上是变相的单词正则表达式):

import re

num_matches = 3

def get_words(input):
    return re.compile('\w+').findall(input)

my_string = 'she said he replied'
my_list = ['This is a cool sentence', 'This is another sentence','she said hello he replied goodbye', 'she replied', 'Some more sentences in here', 'et cetera et cetera...']

my_string_word_set = set(get_words(my_string))
my_list_words_set = [set(get_words(x)) for x in my_list]

result = [len(my_string_word_set.intersection(x)) >= num_matches for x in my_list_words_set]
print(result)

结果

[False, False, True, False, False, False]

对于第 2 部分,类似这样的方法应该可行,但它不是一个超级干净的解决方案。如果您不希望它们按顺序排列,而是彼此相邻,请检查索引是否相隔 1。

words = get_words(my_string)
first_and_last = [words[0], words[-1]]
my_list_dicts = []
for sentence in my_list:
    word_dict = {}
    sentence_words = get_words(sentence)
    for i, word in enumerate(sentence_words):
        word_dict[word] = i
    my_list_dicts.append(word_dict)

result2 = []
for word_dict in my_list_dicts:
    if all(k in word_dict for k in first_and_last) and word_dict[first_and_last[0]] < word_dict[first_and_last[1]]:
        result2.append(True)
    else:
        result2.append(False)

print(result2)

结果:

[False, False, True, True, False, False]

您也可以使用 flashtext 来完成此操作

from flashtext import KeywordProcessor

kw_list = my_string.split()
kp = KeywordProcessor()
kp.add_keywords_from_list(kw_list) # add keyword that you are looking for 

def func_(x):
    kw = kp.extract_keywords(x)  # this will return all keyword present in the string
    return len(set(kw)) # now you find the sum of unique kw found in string 

print(list(map(func_, my_list)))
[0, 0, 4, 2, 0, 0]