Bigram检测:将字符串与列表进行比较以合并某些子字符串

时间:2017-06-29 11:46:16

标签: python string list substring

考虑到我有一个字符串:

text = "You are good at data mining and machine learning"

以及可能的双子座列表:

bigrams = ["data mining", "machine learning"]

我怎么能在文本中检测到那些双字母并将两个单词合并在一起,这样我的结果就像是一个字符串:

new_text = "You are good at data_mining and machine_learning"

我需要将它应用于更大的字符串(语料库)和更长的双字母组列表。

我尝试使用string.replace():

new_text = [x.replace(" ","_") for x in text if x in bigrams]

但这会产生一个空列表。

3 个答案:

答案 0 :(得分:1)

你可以用优雅的方式来做,例如:

input_list = text.split(" ")

def ngrams(input_list, n):
  return zip(*[input_list[i:] for i in range(n)])

其中n在您的情况下应为2。这将返回包含所有bigram组合的元组列表。之后你可以简单地使用列表理解来重新连接每个元组

list_of_bigrams = [bigram[0] + "_" + bigram[1] for bigram in ngrams(input_list,2)]

答案 1 :(得分:1)

这使用re并调用replace以仅在匹配的克数上将空格转换为下划线。

>>> import re
>>> bigrams = ["data mining", "machine learning"]
>>> text = "You are good at data mining and machine learning"
>>> re.sub('('+'|'.join('\\b'+re.escape(g)+'\\b' for g in bigrams)+')', 
...        lambda m: m.group(0).replace(' ', '_'), text)
'You are good at data_mining and machine_learning'

理想情况下,这是最有效的解决方案,因为查找字符串中一组字符串的非重叠出现可以及时完成,主要取决于字符串的长度而不是字符串集的大小,一旦该集合被加上前缀索引。

答案 2 :(得分:0)

最简单的方法:

for bigram in bigrams:
    text = text.replace(bigram, "_".join(split(bigram)))

或克里斯指出

for bigram in bigrams:
    text = text.replace(bigram, bigram.replace(" ", "_"))

我不确定哪个更快。