确定一个单词列表是不是在一个句子中?

Posted

技术标签:

【中文标题】确定一个单词列表是不是在一个句子中?【英文标题】:Determine if a list of words is in a sentence?确定一个单词列表是否在一个句子中? 【发布时间】:2012-10-17 02:20:37 【问题描述】:

有没有办法(Pattern 或 Python 或 NLTK 等)检测句子中是否包含单词列表。

The cat ran into the hat, box, and house. | The list would be hat, box, and house

这可以是字符串处理的,但我们可能有更通用的列表:

The cat likes to run outside, run inside, or jump up the stairs. |

List=run outside, run inside, or jump up the stairs.

这可能在段落的中间或句子的结尾,这会使事情变得更加复杂。

我使用 Pattern for python 已经有一段时间了,但我没有看到解决这个问题的方法,我很好奇是否有使用模式或 nltk(自然语言工具包)的方法。

【问题讨论】:

你的句子是整个字符串,还是你想在更大的文本中匹配一个句子并只返回那个句子? 单词必须按照给定的顺序出现吗?即,您是在寻找子集还是子序列? 包含这些单词的字符串是否有效?比如“that”有一个单词“hat”作为子串。 抱歉耽搁了,但我不是在寻找一个句子中已知单词的列表。如果有可能有一个句子并且能够知道其中是否有单词列表,我很感兴趣。例如,如果我有:“我喜欢走路、跑步和骑自行车”。我希望我的代码查看这句话并告诉我存在一个列表,它是:步行、跑步和骑自行车。更复杂的是,我不能保证我会有那种确切的格式。我可以在一个列表中有两个单词,等等。我最初的想法是只看倒数第二个单词,如果它是 and,或者然后开始向后阅读“,”作为分隔符 【参考方案1】:

使用Trie,您将能够实现这是O(n),其中n 是使用带有O(n) 的单词列表构建一个trie 后单词列表中的单词数@ 其中@ 987654326@ 是列表中的单词数。

算法

将句子分成由空格分隔的单词列表。 对于每个单词,检查它是否在 trie 中有一个键。即该单词存在于列表中 如果退出,则将该单词添加到结果中,以跟踪列表中有多少单词出现在句子中 跟踪具有has subtrie的单词,当前单词是单词列表中较长单词的前缀 对于此单词中的每个单词,通过将其扩展为当前单词,它可以是单词列表中的键或子句 如果它是一个 subtrie,那么我们将它添加到 extend_words 列表中,并查看与下一个单词连接是否能够获得完全匹配。

代码

import pygtrie
listOfWords = ['word1', 'word2', 'word3', 'two words']

trie = pygtrie.StringTrie()
trie._separator = ' '
for word in listOfWords:
  trie[word] = True

print('s', trie._separator)

sentence = "word1 as word2 a fword3 af two words"
sentence_words = sentence.split()
words_found = 
extended_words = set()

for possible_word in sentence_words:
  has_possible_word = trie.has_node(possible_word)

  if has_possible_word & trie.HAS_VALUE:
    words_found[possible_word] = True

  deep_clone = set(extended_words)
  for extended_word in deep_clone:
    extended_words.remove(extended_word)

    possible_extended_word = extended_word + trie._separator + possible_word
    print(possible_extended_word)
    has_possible_extended_word = trie.has_node(possible_extended_word)

    if has_possible_extended_word & trie.HAS_VALUE:
      words_found[possible_extended_word] = True

    if has_possible_extended_word & trie.HAS_SUBTRIE:
      extended_words.update(possible_extended_word)


  if has_possible_word & trie.HAS_SUBTRIE:
    extended_words.update([possible_word])

print(words_found)
print(len(words_found) == len(listOfWords))

如果您的单词列表很大并且您不希望每次都对其进行迭代,或者您对同一个单词列表有大量查询,这将非常有用。

The code is here

【讨论】:

【参考方案2】:

使用from nltk.tokenize import sent_tokenize 怎么样?

sent_tokenize("Hello SF Python. This is NLTK.")
["Hello SF Python.", "This is NLTK."]

那么你可以这样使用那个句子列表:

for sentence in my_list:
  # test if this sentence contains the words you want
  # using all() method 

更多信息here

【讨论】:

这是我能想到的最接近的解决方案。我只是使用模式(或者您可以使用 NLTK)来拆分句子。但在此之前,我通过找出最后一个“,”之后的下一个单词是否是 and 或 but 来检查是否有一个列表。如果是我备份并阅读上一个','。我为我的列表设置了最多 3 个字,这让我尽可能接近解决方案。问题是,如果我有“猫跳过帽子、盒子和杯子”,列表的第一部分可能是“跳过帽子”,这对于我正在做的事情是可以接受的。【参考方案3】:

根据我从您的问题中得到的信息,我认为您想搜索列表中的所有单词是否都出现在一个句子中。

一般要搜索一个列表元素,在一个句子中,可以使用all函数。如果其中的所有参数都为真,则返回真。

listOfWords = ['word1', 'word2', 'word3', 'two words']
sentence = "word1 as word2 a fword3 af two words"

if all(word in sentence for word in listOfWords):
    print "All words in sentence"
else:
    print "Missing"

输出:-

"All words in sentence"

我认为这可能符合您的目的。如果没有,那你可以澄清一下。

【讨论】:

好的,那么 Downvoter,您能否发表评论,而不是在投票后默默地坐着?【参考方案4】:
all(word in sentence for word in listOfWords)

【讨论】:

以上是关于确定一个单词列表是不是在一个句子中?的主要内容,如果未能解决你的问题,请参考以下文章

给定单词相似度推断句子相似度

2021-10-16:单词拆分 II。给定一个非空字符串 s 和一个包含非空单词列表的字典 wordDict,在字符串中增加空格来构建一个句子,使得句子中所有的单词都在词典中。返回所有这些可能的句子。

从单词列表中查找给定句子的字谜

在字符串中查找特定单词的位置

使用 grep 或 sed 仅保留另一个单词列表文件中的单词

计算包含来自其他列表Python的单词的句子数[关闭]