Python无法解析带UTF-8 BOM的CSV为列表,求解决方案
解决带BOM的UTF-8 CSV读取问题(含逗号列值)
问题根源拆解
- 编码不匹配:ads-test.csv是带BOM的UTF-8编码,强行用utf-16读取必然报错,需用
utf-8-sig编码(会自动移除UTF-8 BOM) - 分隔符错误:你的代码硬指定了
delimiter='\t',但ads-test.csv实际是逗号分隔;csv模块默认会自动处理带引号的含逗号列值,只要分隔符正确就能正常拆分 - 表头处理不够健壮:手动判断表头的方式容易出错,用csv模块自带的工具更可靠
修改后的可运行代码
rtc_csv_file = "csv_migration\\rtc-test.csv" ads_csv_file = "csv_migration\\ads-test.csv" import csv # 读取CSV并转换为以ID为键的字典 def read_csv_as_map(csv_filename, id_format, encoding_var): print(f'filename: {csv_filename}, id_format: {id_format}, encoding: {encoding_var}') result_dict = {'rows': {}} try: with open(csv_filename, 'r', encoding=encoding_var) as read_obj: # 自动检测CSV的分隔符和格式规则 dialect = csv.Sniffer().sniff(read_obj.read(1024)) read_obj.seek(0) # 回到文件开头继续读取 csv_reader = csv.reader(read_obj, dialect) csv_cols = next(csv_reader) # 直接读取表头行 result_dict['csv_cols'] = csv_cols print(f'csv_cols= {csv_cols}') # 查找目标ID列的索引 try: id_index = csv_cols.index(str(id_format)) except ValueError: print(f'错误:未找到列名 {id_format}') return result_dict # 遍历数据行并构建字典 for row in csv_reader: if len(row) <= id_index: print(f'警告:行数据长度不足,跳过该行:{row}') continue row_id_val = row[id_index] print(f'row_id_val= {row_id_val}') result_dict['rows'][row_id_val] = row print('读取完成') return result_dict except Exception as e: print(f'err= {e}') return result_dict # 分别读取两个文件,注意编码差异 rtc_dict = read_csv_as_map(rtc_csv_file, 'Id', 'utf-16') ads_dict = read_csv_as_map(ads_csv_file, 'ID', 'utf-8-sig')
关键修改说明
- 编码适配:ads文件使用
utf-8-sig编码,自动处理UTF-8 BOM,解决编码报错问题 - 智能分隔符检测:通过
csv.Sniffer自动识别文件的分隔符(逗号/制表符等),同时自动处理带引号的含逗号列值,无需手动拆分字符串 - 健壮性优化:增加了ID列不存在、行数据长度不足的异常处理,避免程序崩溃
- 更规范的CSV读取:用
next(csv_reader)直接读取表头,符合csv模块的标准用法
内容的提问来源于stack exchange,提问作者POVR2
相关产品推荐
相关产品推荐

