在Python开发中,CSV(逗号分隔值)是最常碰到的数据交换格式之一。无论是业务系统导出的报表,还是爬虫落地的轻量数据,基本都离不开这种纯文本表格。Python自带的标准库已经提供了完整的处理工具,不需要额外安装组件就能完成绝大多数读写任务。

使用csv模块读取CSV文件
标准库中的csv模块通过reader对象把每一行转化成列表,字段严格按照CSV规范解析。下面示例展示如何读取一个本地文件,并打印前几行内容。
import csv
# 以只读模式打开CSV,指定编码避免中文乱码
with open('data.csv', 'r', encoding='utf-8') as f:
reader = csv.reader(f)
for i, row in enumerate(reader):
if i < 5:
print(row)
else:
break
上面的代码利用上下文管理器自动关闭文件,csv.reader会把每行文本按逗号切分,同时正确处理用双引号包裹、内部含逗号的字段。例如"北京,朝阳区"不会被拆成两列。如果CSV使用分号或其他分隔符,可在创建reader时传入delimiter参数。
当文件首行是列名时,DictReader更加方便,它把每行变成字典,键就是表头。这样在程序里可以用字段名而不是索引访问数据,可读性明显更好。
import csv
with open('user.csv', 'r', encoding='utf-8') as f:
dr = csv.DictReader(f)
for row in dr:
# 直接用列名取数据
print(row['name'], row['age'])
DictReader在内部先读表头构建字段列表,后续行映射成有序字典。它的缺点是相比普通reader多一次表头解析,但在绝大多数业务场景下这点开销可以忽略。如果列名含有空格或特殊符号,访问时保持与文件完全一致即可。
写入CSV文件的正确方式
写文件时最容易踩的坑是在Windows上出现多余空行。原因是文本模式默认换行翻译与csv自己写的rn冲突。解决办法是以newline=''打开文件,让csv模块完全控制换行符。
import csv
rows = [
['id', 'product', 'price'],
[1, '键盘', 99],
[2, '鼠标', 59]
]
with open('out.csv', 'w', encoding='utf-8', newline='') as f:
writer = csv.writer(f)
writer.writerows(rows)
writerows可一次写入多行,writerow则单行写入。若想输出字典形式,用DictWriter并先调用writeheader写表头。注意字段顺序由fieldnames决定,跟字典里的顺序无关。
import csv
data = [
{'name': '张三', 'score': 88},
{'name': '李四', 'score': 92}
]
with open('score.csv', 'w', encoding='utf-8', newline='') as f:
dw = csv.DictWriter(f, fieldnames=['name', 'score'])
dw.writeheader()
dw.writerows(data)
这种写法在生成报表或接口回写数据时非常稳妥。如果数据里本身含有逗号或引号,csv模块会自动加引号包裹,不需要手动处理转义,避免下游解析出错。
处理编码与大文件
实际文件常不是utf-8,例如Windows导出多为gbk。打开时把encoding换成对应值即可,否则会抛出UnicodeDecodeError。对于超大文件,不要一次性readlines,直接遍历reader对象就是流式处理,内存占用恒定。
import csv
count = 0
with open('big.csv', 'r', encoding='gbk', newline='') as f:
reader = csv.reader(f)
next(reader) # 跳过表头
for row in reader:
count += 1
# 此处可做聚合统计,不保存全量
print('总行数', count)
如果必须在处理中转换编码,可借助io.TextIOWrapper包装二进制流。这样既能控制分隔符,也能灵活切换编解码器,适合异构系统间的数据清洗管道。
csv模块与pandas的取舍
当数据量中等且要做复杂统计,pandas的read_csv一步到位成DataFrame,支持类型推断、缺失值处理。但pandas本身依赖numpy,内存常是数据体积数倍。下表列出两者常见差异:
| 维度 | csv模块 | pandas |
|---|---|---|
| 依赖 | 标准库无依赖 | 需安装第三方包 |
| 内存 | 流式低占用 | 全量加载较高 |
| 开发效率 | 基础操作为主 | 分析接口丰富 |
简单迁移、配置导出、日志解析用csv模块足够;需要分组、透视、画图再上pandas。二者也可以通过分块读取结合使用,例如pandas的read_csv带chunksize参数,本质也是流式思路。
掌握这些写法之后,面对各种逗号分隔值文件都不会手足无措。先判断文件规模与后续用途,再选标准库还是数据分析库,能省掉不少调试时间。