如何从行长度不一致的CSV文件创建列表并避免索引错误?
问题与解决
问题描述
我有一个105行9列的.csv文件,部分行仅在前4列有有效值,运行Python代码时触发IndexError: list index out of range错误,需要创建元素列表并将缺失列值填充为0。
原代码:
from elements import Element import csv filename = "elements.csv" fields = [] elements_list = [] with open(filename, 'r') as csvfile: csvreader = csv.reader(csvfile, delimiter=';') fields = next(csvreader) for row in csvreader: elements_list.append(Element(row[0], row[1], row[2], row[3], row[4], row[5], row[6], row[7], row[8]))
错误信息:IndexError: list index out of range
CSV示例(部分):
Element,Number,Symbol,Weight,Boil,Melt,Density,Vapour,Fusion, Aluminum,13,Al,26.98,2723.16,933.16,2700,284.34,10.68, Silicon,14,Si,28.09,2953.16,1683.16,2330,170.02,46.48, Phosphorus,15,P,30.98, Sulfur,16,S,32.06,717.76,392.16,2070,12.60,1.42, Chlorine,17,Cl,35.45,238.46,172.16,1560,10.22,3.22, Argon,18,Ar,39.95,87.36,83.76,1400,6.53,1.18,
期望效果:缺失值填充为0,例如:
Silicon,14,Si,28.09,2953.16,1683.16,2330,170.02,46.48, Phosphorus,15,P,30.98,0,0,0,0,0, Sulfur,16,S,32.06,717.76,392.16,2070,12.60,1.42,
解决方案
报错根源是部分行的列数不足9,直接通过索引访问row[4]至row[8]会超出列表范围。以下是两种可行的处理方式:
方法1:直接扩展行并填充0
通过列表拼接将每行扩展到9个元素,缺失部分补0,同时修正CSV分隔符的问题(原CSV用逗号分隔,代码里误写为分号):
from elements import Element import csv filename = "elements.csv" elements_list = [] total_cols = 9 # 固定总列数 with open(filename, 'r') as csvfile: # 修正分隔符为逗号,匹配CSV格式 csvreader = csv.reader(csvfile, delimiter=',') next(csvreader) # 跳过表头行 for row in csvreader: # 清洗行数据:移除空字符串(处理行尾逗号导致的空元素) cleaned_row = [item.strip() for item in row if item.strip()] # 填充0至指定列数,若行元素过多则截取前9个 padded_row = cleaned_row + ['0'] * (total_cols - len(cleaned_row)) padded_row = padded_row[:total_cols] # 用解包方式传递参数,避免逐个写索引 elements_list.append(Element(*padded_row))
方法2:使用DictReader映射字段(更易维护)
借助csv.DictReader按字段名读取数据,再遍历字段填充缺失值:
from elements import Element import csv filename = "elements.csv" elements_list = [] # 定义所有字段名,与CSV表头对应 field_names = ["Element", "Number", "Symbol", "Weight", "Boil", "Melt", "Density", "Vapour", "Fusion"] with open(filename, 'r') as csvfile: csvreader = csv.DictReader(csvfile, fieldnames=field_names) next(csvreader) # 跳过表头 for row in csvreader: # 遍历字段,将空值替换为0 for key in field_names: if not row[key].strip(): row[key] = '0' # 按字段顺序提取值并创建Element对象 element_vals = [row[key] for key in field_names] elements_list.append(Element(*element_vals))
内容的提问来源于stack exchange,提问作者Sein
相关产品推荐
相关产品推荐

