跑一个数据清洗脚本,读 CSV 按某列过滤,再按索引取第二列,报错 IndexError: list index out of range。文件前一版还能跑,加了过滤条件就崩。
这个错只有三种来源
要么列表本身是空的,要么索引比长度大,要么在循环里一边遍历一边删元素导致长度变了。Python 的索引从 0 开始,长度 3 的列表最大下标是 2,写 rows[3] 必崩。
最常见的是过滤后长度变了
先 len(rows) 拿到 200,过滤掉空行剩 0 行,后面的 rows[0][1] 自然越界。加过滤条件的时候,顺手加上边界判断:
if not rows: print('过滤后为空'); else: print(rows[0][1])循环里删除元素必踩坑
for 循环拿的是原始长度,边跑边 remove 会让后面的元素前移,最后一个下标就越界。改成倒序删,或者用列表推导重建:
rows = [r for r in rows if r.strip()]多维列表报错可能在第二层
rows[0][1] 崩了,未必是第一层有问题。某一行只有一列时,取第二个元素就越界。先把每行长度打出来,或者用 len(row) 大于 1 判断。JSON 解析出来的结构也一样,字段缺失和空字符串不是一回事。
别用 range(len) 硬取
想要下标就用 enumerate,想要最后一个元素用 rows[-1],想切一段用 rows[1:3],切片越界不报错,返回空列表。空列表取最后一个一样会崩,前面得先判空。
换成 pandas 能省掉大半这类错
按列名取数据,列不存在会报 KeyError,比下标越界好定位。iloc 按位置、loc 按标签,两个混用是新的坑。几十行的小脚本没必要上 pandas,处理几百兆的表就值得换。
排查时把现场打出来
在报错行上面加一句 print(len(rows), idx, rows[:2]),看看到底是空还是索引错位。线上环境不方便打印,就用 try except IndexError 兜住,记录行号和当时的长度。
处理完回头看,这类错九成不是语法问题,是数据比预期脏。过滤条件加上去的那一刻,就该同步加上空值判断。