字典键值顺序变更导致Python脚本输出异常的问题排查
问题原因分析
你的代码里处理第一个待替换词(words[0])的逻辑存在致命问题:遍历combo_dict所有键值对时,只要当前键不匹配words[0],就会把SubWordOne重置为原始的fileLine。
当字典顺序改成{'Shp': 'Shop', 'Mngr': 'Manager'}时,循环先处理Shp(匹配words[0],生成正确替换后的行),接着处理Mngr(不匹配words[0]),此时SubWordOne被强行改回原始行,之前的Shp→Shop替换直接被覆盖,最终输出里Shp没被替换。
修复方案
完全可以简化替换逻辑,不用遍历整个字典,直接利用字典的键查找特性完成替换,既高效又不会出错:
优化后的代码
import re combo_dict = { 'Shp': 'Shop', 'Mngr': 'Manager' } # 修正正则字符范围:原[A-z]包含特殊字符,改用[A-Za-z]仅匹配大小写字母 rexCapDoubleWord = r'(?s)\s([A-Za-z]+\s[A-Za-z]+)$' fileLines = ['001 AALTONEN Alan Roy 2 Berkeley_Road,_Welltown Shp Mngr'] for idx, fileLine in enumerate(fileLines): try: # 获取行尾的两个目标词 regexCapDouble = re.search(rexCapDoubleWord, fileLine).group(1) if regexCapDouble: words = regexCapDouble.split() # 用字典获取替换值,找不到则保留原词 word1 = combo_dict.get(words[0], words[0]) word2 = combo_dict.get(words[1], words[1]) # 整体替换行尾的两个词 new_line = re.sub(rexCapDoubleWord, f' {word1} {word2}', fileLine) fileLines[idx] = new_line except AttributeError: # 没有匹配到目标内容时跳过 pass for fileLine in fileLines: print(fileLine)
关键改进点
- 删掉了冗余的字典循环,用
dict.get()直接获取替换值,彻底避免循环中覆盖变量的问题 - 修正了正则的字符范围,避免匹配到非字母的特殊字符
- 用
enumerate遍历列表直接修改对应元素,比原代码的map+replace更简洁高效 - 针对行尾的两个词整体替换,减少多次
re.sub可能带来的意外匹配
通用替换方案(适用于多位置替换)
如果后续需要替换文本中任意位置的目标词,可以用一次性匹配所有字典键的正则,批量替换:
import re combo_dict = {'Shp': 'Shop', 'Mngr': 'Manager'} fileLines = ['001 AALTONEN Alan Roy 2 Berkeley_Road,_Welltown Shp Mngr'] # 构建匹配所有字典键的正则,\b确保匹配完整单词 pattern = re.compile(r'\b(' + '|'.join(re.escape(key) for key in combo_dict.keys()) + r')\b') # 批量替换所有匹配项 fileLines = [pattern.sub(lambda match: combo_dict[match.group()], line) for line in fileLines] for line in fileLines: print(line)
这种方式不管字典键的顺序如何,都能准确替换所有匹配的目标词。
内容的提问来源于stack exchange,提问作者Dave
相关产品推荐
相关产品推荐

