基于字典/列表对单词进行标记的Python方法
我有一个基因名称的字典:
gene_dict = {"repA1":1, "leuB":1}
# the actual dictionary is longer, around ~30K entries.
# or in list format
# gene_list = ["repA1", "leuB"]
我想做的是,给定任何一句话,我们要在上面的字典中查找包含的词汇,然后给它们打标签。
比如说,给定这句话:
mytext = "xxxxx repA1 yyyy REPA1 zzz."
它会被标记为:
xxxxx <GENE>repA1</GENE> yyyy <GENE>REPA1</GENE> zzz.
有没有什么有效的方法可以做到这一点?实际上,我们需要处理几百万句子。
2 个回答
1
如果大部分句子都很短,并且用单个空格分开,比如:
gene_dict = {"repA1":1, "leuB":1}
format_gene = "<GENE>{}</GENE>".format
mytext = " ".join(format_gene(word) if word in gene_dict else word for word in mytext.split())
这样做会更快。
对于稍微长一点的句子,或者那些你不能用 " ".join
处理的句子,使用多个 .replace
可能会更有效或者更正确:
gene_dict = {"repA1":1, "leuB":1}
genes = set(gene_dict)
format_gene = "<GENE>{}</GENE>".format
to_replace = genes.intersection(mytext.split())
for gene in to_replace:
mytext = mytext.replace(gene, format_gene(gene))
这里每种方法都假设句子的 split
操作不会花费太多时间,这样假设是合理的,因为 genes_dict
通常会比句子长得多。
3
如果你的“gene_list”不是特别特别长的话,可以使用一个编译好的正则表达式,比如说
import re
gene_list = ["repA1", "leuB"]
regexp = re.compile('|'.join(gene_list), flags=re.IGNORECASE)
result = re.sub(regexp, r'<GENE>\g<0></GENE>', 'xxxxx repA1 yyyy REPA1 zzz.')
然后把它放进一个循环里,去处理你所有的句子。我觉得这样应该会很快。