【问题标题】:Python string matching - Find if certain number of words in a list of words exist in a sentence in another listPython字符串匹配 - 查找单词列表中的特定数量的单词是否存在于另一个列表中的句子中
【发布时间】:2020-03-02 05:34:54
【问题描述】:

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

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”出现在my_list的索引3处的“她回复”中,返回True。

【问题讨论】:

    标签: python string list string-matching


    【解决方案1】:

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

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

    nltk wordpunct_tokenize vs word_tokenize

    Python re.split() vs nltk word_tokenize and sent_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)
    

    结果

    [假、假、真、假、假、假]

    对于第 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)
    

    结果:

    [假、假、真、真、假、假]

    【讨论】:

      【解决方案2】:

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

      首先在my_list中的字符串中构建一个所有单词的集合,使用集合并集:

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

      然后检查交叉点是否有长度&gt;= 3

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

      【讨论】:

        【解决方案3】:

        使用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 已经发布了我会告诉你做什么。

        【讨论】:

        • 它将为“另一个”中的“他”返回 True
        【解决方案4】:

        您也可以使用 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]
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2022-06-10
          • 1970-01-01
          • 1970-01-01
          • 2017-02-28
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多