Python中如何高效将句子中指定列表内单词替换为特定词
高效实现字典映射的文本替换
问题描述
我有如下字典映射:
{ 'a': ['a1','a2','a3'], 'b': ['b1', 'b2'], 'c': ['c1', 'c2', 'c3', 'c4'] }
给定一个句子,需要把所有出现的a1、a2、a3替换为a,同理b1、b2替换为b,c1-c4替换为c。请问怎么高效实现这个功能?
以下是我当前的实现代码:
def word_replacer(text): s = { 'a': ['a1','a2','a3'], 'b': ['b1', 'b2'], 'c': ['c1', 'c2', 'c3', 'c4'] } words = text.split(" ") for idx, word in enumerate(words): changed_word=[k for k, v in s.items() if word in [vals.lower() for vals in v]] if ((len(changed_word)>0) and (word != changed_word[0])): words[idx] = changed_word[0] result = " ".join(words) return result
优化方案
当前实现的问题在于,每次遍历单词时都要完整遍历原字典的所有值列表,还会重复生成小写值列表,字典规模越大,效率越低。下面是更高效的实现思路:
1. 构建反向映射字典(最优方案)
把原字典反转成{子项: 目标替换值}的结构,这样每次查找替换的时间复杂度是O(1),整体效率大幅提升:
def word_replacer(text): # 原映射字典 s = { 'a': ['a1','a2','a3'], 'b': ['b1', 'b2'], 'c': ['c1', 'c2', 'c3', 'c4'] } # 构建反向映射:子项 -> 目标替换值 reverse_map = {} for target, items in s.items(): for item in items: reverse_map[item.lower()] = target # 保留原代码的小写匹配逻辑 # 处理文本 words = text.split(" ") # 用列表推导式简化替换逻辑 replaced_words = [reverse_map.get(word.lower(), word) for word in words] return " ".join(replaced_words)
优化点说明
- 反向映射预构建:提前把所有需要替换的子项和目标值一一对应,避免每次查找都遍历原字典,时间复杂度从O(n*m)(n为单词数,m为字典键值对数量)降到O(n)。
- 简化替换逻辑:用字典的
get方法直接处理匹配与不匹配的情况,无需额外判断列表长度和单词是否相等,代码更简洁。 - 列表推导式:相比原代码的循环+枚举,写法更高效直观。
2. 处理含标点的场景(可选)
如果句子中包含标点(比如a1,),原代码的split会把标点和单词绑定,导致无法匹配。可以用正则表达式提取独立单词,解决这个问题:
import re def word_replacer(text): s = { 'a': ['a1','a2','a3'], 'b': ['b1', 'b2'], 'c': ['c1', 'c2', 'c3', 'c4'] } reverse_map = {} for target, items in s.items(): for item in items: reverse_map[item.lower()] = target # 用正则匹配单词(包含字母数字) def replace_match(match): word = match.group() return reverse_map.get(word.lower(), word) return re.sub(r'\w+', replace_match, text)
这个版本可以处理带标点的句子,比如"a1, b2! c3"会被替换成"a, b! c"。
内容的提问来源于stack exchange,提问作者S_S
相关产品推荐
相关产品推荐

