基于字典/列表对单词进行标记的Python方法

2 投票
2 回答
1382 浏览
提问于 2025-04-18 07:35

我有一个基因名称的字典:

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.')

然后把它放进一个循环里,去处理你所有的句子。我觉得这样应该会很快。

撰写回答