代码触发ValueError: substring not found,求排查build_shift_dict函数问题
排查并修复你的凯撒密码移位字典构建代码
首先,咱们直接说报错的核心原因:当循环到大写字母或者非字母字符(比如空格、标点)时,你调用了lower.index(j),但这些字符根本不在string.ascii_lowercase里,所以Python找不到对应的子串,直接抛出了ValueError: substring not found。
接下来咱们一步步拆解问题并修复:
问题点梳理
- 大小写判断逻辑顺序错误:你先调用
lower.index(j)再判断是否小写,导致大写/非字母字符直接触发报错 - 移位越界处理错误:
string.ascii_lowercase的索引是0-25(共26个字符),你判断>26是错误的,而且没有处理循环移位(比如'z'移1位应该变成'a') - 未处理非字母字符:如果消息里有空格、标点,你的代码会直接跳过处理,导致字典缺失这些键
修复后的代码
import string class Cipher: def __init__(self, message_text): self.message_text = message_text def build_shift_dict(self, shift): lower = string.ascii_lowercase upper = string.ascii_uppercase shift_dict = {} for char in self.message_text: if char.islower(): # 小写字符:计算循环移位后的索引 original_idx = lower.index(char) new_idx = (original_idx + shift) % 26 shift_dict[char] = lower[new_idx] elif char.isupper(): # 大写字符:同理处理 original_idx = upper.index(char) new_idx = (original_idx + shift) % 26 shift_dict[char] = upper[new_idx] else: # 非字母字符:直接保留原字符(可根据需求修改) shift_dict[char] = char return shift_dict
关键修复说明
- 先判断字符类型再取索引:先检查字符是小写/大写/非字母,再去对应的字符串里找索引,彻底避免了
index()找不到的错误 - 用模运算处理循环移位:
(original_idx + shift) % 26自动处理越界情况,比如'z'(索引25)移1位后,(25+1)%26=0,对应字母'a' - 兼容非字母字符:空格、标点等字符会直接保留在字典中,不会丢失或报错
测试示例
如果你的消息是"Hello, Stack!",移位值为3,调用build_shift_dict(3)会返回:
{'H': 'K', 'e': 'h', 'l': 'o', 'o': 'r', ',': ',', ' ': ' ', 'S': 'V', 't': 'w', 'a': 'd', 'c': 'f', 'k': 'n', '!': '!'}
内容的提问来源于stack exchange,提问作者f-person
相关产品推荐
相关产品推荐

