如何避免Python读取可变行数文件时出现list index out of range异常
解决列表索引越界问题
问题根源
你的文本文件只有26行,读取后lines列表的索引范围是0~25(列表索引从0开始),但subs里直接访问了lines[26]、lines[28]、lines[30]这些超出列表长度的索引,自然会触发list index out of range异常。同时你需要兼容后续文件行数不确定的情况,又不想修改subs的结构,核心是要保证访问任意索引时都不会报错。
解决方案
方案1:给lines补全空字符串
在读取文件后,将lines补全到足够长度(比如31个元素,因为你用到的最大索引是30),超出原文件行数的部分用空字符串填充:
with open('txt_file.txt') as file: lines = [line.rstrip() for line in file] # 补全到31个元素,确保索引0~30都有对应值 lines += [''] * (31 - len(lines)) subs = [((0, 3), lines[1] +'\n'+lines[2]), ((4, 7), lines[3] +'\n'+lines[4]), ((8, 11), lines[5] +'\n'+lines[6]), ((12, 15), lines[7] +'\n'+lines[8]), ((16, 19), lines[9] +'\n'+lines[10]), ((20, 23), lines[11] +'\n'+lines[12]), ((24, 27), lines[13] +'\n'+lines[14]), ((28, 31), lines[15] +'\n'+lines[16]), ((32, 35), lines[17] +'\n'+lines[18]), ((36, 39), lines[19] +'\n'+lines[20]), ((40, 43), lines[21] +'\n'+lines[22]), ((44, 47), lines[23] +'\n'+lines[24]), ((48, 51), lines[25] +'\n'+lines[26]), ((52, 55), lines[27] +'\n'+lines[28]), ((56, 59), lines[29] +'\n'+lines[30]),]
这样不管原文件有多少行,lines的索引0~30都能安全访问,不存在的行就用空字符串替代,不会触发异常。
方案2:写一个安全获取元素的辅助函数
如果不想修改lines本身,可以定义一个函数,当索引超出范围时返回空字符串:
def get_line(lines, idx): return lines[idx] if idx < len(lines) else '' with open('txt_file.txt') as file: lines = [line.rstrip() for line in file] subs = [((0, 3), get_line(lines,1) +'\n'+get_line(lines,2)), ((4, 7), get_line(lines,3) +'\n'+get_line(lines,4)), ((8, 11), get_line(lines,5) +'\n'+get_line(lines,6)), ((12, 15), get_line(lines,7) +'\n'+get_line(lines,8)), ((16, 19), get_line(lines,9) +'\n'+get_line(lines,10)), ((20, 23), get_line(lines,11) +'\n'+get_line(lines,12)), ((24, 27), get_line(lines,13) +'\n'+get_line(lines,14)), ((28, 31), get_line(lines,15) +'\n'+get_line(lines,16)), ((32, 35), get_line(lines,17) +'\n'+get_line(lines,18)), ((36, 39), get_line(lines,19) +'\n'+get_line(lines,20)), ((40, 43), get_line(lines,21) +'\n'+get_line(lines,22)), ((44, 47), get_line(lines,23) +'\n'+get_line(lines,24)), ((48, 51), get_line(lines,25) +'\n'+get_line(lines,26)), ((52, 55), get_line(lines,27) +'\n'+get_line(lines,28)), ((56, 59), get_line(lines,29) +'\n'+get_line(lines,30)),]
这个方案更灵活,不管后续用到多大的索引,只要在函数里判断就能避免越界,同时完全不用修改subs的结构逻辑,只是把lines[idx]替换成get_line(lines, idx)。
内容的提问来源于stack exchange,提问作者Kukkik
相关产品推荐
相关产品推荐

