Python CSV 处理完全指南:从基础读取到高级写入技巧
文章目录
环境:Python 3.x
适用人群:Python 初学者、数据处理入门者、需要处理CSV文件的开发者
前置知识:Python基础语法、文件操作基础
引言:为什么 CSV 处理总是让人头疼?
CSV(Comma-Separated Values)作为最常用的数据交换格式之一,看似简单却暗藏玄机。你是否也遇到过这些令人抓狂的问题?
🚨 常见痛点
- 跨平台兼容性问题:在 Windows 上打开 CSV 时出现多余空行
- 编码混乱:中文字符显示为乱码
- 类型错误:使用
csv.DictWriter时遇到AttributeError: 'list' object has no attribute 'keys' - 缩进陷阱:代码逻辑正确却报
IndentationError - 数据丢失:特殊字符(如逗号、引号)处理不当导致数据损坏
这些问题看似简单,却让很多开发者在数据处理的第一步就陷入困境。本文将带你系统掌握 Python 内置 csv 模块,从基础读写到高级用法,再到生产环境的最佳实践。
📚 你将学到什么
| 技能点 | 掌握程度 | 应用场景 |
|---|---|---|
| CSV 文件正确读写 | ⭐⭐⭐⭐⭐ | 数据导入导出 |
csv.reader vs csv.DictReader |
⭐⭐⭐⭐ | 按需选择读取方式 |
csv.writer vs csv.DictWriter |
⭐⭐⭐⭐ | 灵活写入数据 |
| Windows 换行符问题 | ⭐⭐⭐⭐⭐ | 跨平台兼容 |
| 常见错误排查 | ⭐⭐⭐⭐ | 快速定位问题 |
| 性能优化技巧 | ⭐⭐⭐ | 大数据量处理 |
🎯 本文特色
- 实战导向:每个知识点都配有可运行的代码示例
- 问题驱动:针对常见错误提供解决方案
- 最佳实践:总结生产环境中的经验教训
- 性能对比:不同方法的效率分析
让我们开始这段 CSV 处理之旅,彻底告别那些令人头疼的问题!
一、CSV 基础:理解文件结构与读取方式
CSV(Comma-Separated Values)是一种轻量级的表格数据存储格式,每行代表一条记录,字段之间用分隔符(通常是逗号)隔开。虽然名为"逗号分隔",但实际上可以使用多种分隔符:
| 格式 | 分隔符 | 文件扩展名 | 常见场景 |
|---|---|---|---|
| CSV | 逗号 (,) |
.csv |
通用数据交换 |
| TSV | 制表符 (\t) |
.tsv |
生物信息学、日志分析 |
| PSV | 竖线 (` | `) | .psv |
| SSV | 分号 (;) |
.csv |
欧洲地区(避免逗号冲突) |
1.1 基础读取:csv.reader
1.1.1 基本用法
import csv
# 示例数据文件:students.csv
# 学生ID,姓名,性别,年龄,班级,课程名称,课程类型,学分,考试成绩,平时成绩,总评成绩,是否及格,考试日期
# 1001,张三,男,19,计算机1班,Python程序设计,必修课,4,85,90,87,是,2026-01-15
# 1001,张三,男,19,计算机1班,数据结构,必修课,3,78,82,80,是,2026-01-17
# 基础读取 - 逐行读取
with open("students.csv", mode="r", encoding="utf-8", newline="") as file:
reader = csv.reader(file)
# 读取表头
header = next(reader)
print(f"表头: {header}")
print(f"表头数量: {len(header)}")
# 逐行读取数据
for row_num, row in enumerate(reader, start=1):
print(f"第{row_num}行: {row}")
输出结果:
表头: ['学生ID', '姓名', '性别', '年龄', '班级', '课程名称', '课程类型', '学分', '考试成绩', '平时成绩', '总评成绩', '是否及格', '考试日期']
表头数量: 13
第1行: ['1001', '张三', '男', '19', '计算机1班', 'Python程序设计', '必修课', '4', '85', '90', '87', '是', '2026-01-15']
第2行: ['1001', '张三', '男', '19', '计算机1班', '数据结构', '必修课', '3', '78', '82', '80', '是', '2026-01-17']
1.1.2 按列访问数据
import csv
with open("students.csv", mode="r", encoding="utf-8", newline="") as file:
reader = csv.reader(file)
header = next(reader)
# 打印特定列的数据
for row in reader:
student_id = row[0] # 学生ID(索引0)
name = row[1] # 姓名(索引1)
gender = row[2] # 性别(索引2)
score = row[8] # 考试成绩(索引8)
print(f"学号: {student_id}, 姓名: {name}, 性别: {gender}, 成绩: {score}")
1.1.3 使用 DictReader 按列名访问
csv.DictReader 将每行数据转换为字典,键为列名,值为对应的数据:
import csv
with open("students.csv", mode="r", encoding="utf-8", newline="") as file:
# 创建字典读取器
dict_reader = csv.DictReader(file)
# 获取表头(字段名)
fieldnames = dict_reader.fieldnames
print(f"字段名列表: {fieldnames}")
# 逐行读取(每行是一个字典)
for row_num, row_dict in enumerate(dict_reader, start=1):
print(f"\n第{row_num}行数据:")
print(f" 学生ID: {row_dict['学生ID']}")
print(f" 姓名: {row_dict['姓名']}")
print(f" 年龄: {row_dict['年龄']}")
print(f" 考试成绩: {row_dict['考试成绩']}")
输出结果:
字段名列表: ['学生ID', '姓名', '性别', '年龄', '班级', '课程名称', '课程类型', '学分', '考试成绩', '平时成绩', '总评成绩', '是否及格', '考试日期']
第1行数据:
学生ID: 1001
姓名: 张三
年龄: 19
考试成绩: 85
第2行数据:
学生ID: 1001
姓名: 张三
年龄: 19
考试成绩: 78
1.1.4 两种读取方式的对比
| 特性 | csv.reader |
csv.DictReader |
|---|---|---|
| 返回类型 | 列表(list) | 字典(dict) |
| 访问方式 | 索引(如 row[0]) |
键名(如 row['姓名']) |
| 可读性 | 较低(需要记住列顺序) | 较高(通过列名访问) |
| 灵活性 | 固定列顺序 | 列顺序无关紧要 |
| 性能 | 稍快 | 稍慢(需要构建字典) |
| 适用场景 | 列顺序固定的简单CSV | 列较多或列顺序可能变化的CSV |
1.1.5 实战技巧:处理缺失值
import csv
def safe_get(row_dict, key, default="N/A"):
"""安全获取字典值,处理缺失键"""
return row_dict.get(key, default)
with open("students.csv", mode="r", encoding="utf-8", newline="") as file:
dict_reader = csv.DictReader(file)
for row in dict_reader:
# 安全访问,避免KeyError
name = safe_get(row, "姓名", "未知")
score = safe_get(row, "考试成绩", "0")
# 转换为数值类型(如果可能)
try:
score_int = int(score)
except ValueError:
score_int = 0
print(f"{name}的成绩: {score_int}")
1.1.6 性能优化:批量处理大数据
import csv
from collections import defaultdict
def process_large_csv(file_path, batch_size=1000):
"""批量处理大型CSV文件"""
results = defaultdict(list)
with open(file_path, mode="r", encoding="utf-8", newline="") as file:
dict_reader = csv.DictReader(file)
batch = []
for row in dict_reader:
batch.append(row)
# 每处理batch_size行进行一次批量操作
if len(batch) >= batch_size:
process_batch(batch, results)
batch = [] # 清空批次
# 处理剩余数据
if batch:
process_batch(batch, results)
return results
def process_batch(batch, results):
"""处理一批数据"""
for row in batch:
class_name = row.get("班级", "未知班级")
score = int(row.get("考试成绩", 0))
results[class_name].append(score)
📝 本节要点总结
- 基础读取:使用
csv.reader逐行读取,返回列表格式 - 字典读取:使用
csv.DictReader按列名访问,代码更易读 - 性能考虑:小文件直接读取,大文件考虑批量处理
- 错误处理:使用
.get()方法安全访问字典键,避免KeyError
在下一节中,我们将深入探讨 newline="" 参数的重要性,这是解决跨平台兼容性问题的关键。
为什么在写 CSV 时要这么用
csv 模块在写入 CSV 文件时,会自动处理行结束符的标准化问题。如果不指定 newline="" 参数,不同平台上的 Python 解释器会对换行符进行额外的转换,导致 CSV 文件格式异常。
💡 Python 的
open()函数默认会根据操作系统自动转换换行符:在 Windows 上会将\n转换为\r\n,在 Unix/Linux 上则保持\n不变。而csv.writer本身已经负责写入正确的行结束符,双重转换就会出问题。
双重转换导致的格式问题
下面的代码演示了不加 newline="" 参数时可能出现的问题:
import csv
# 错误写法:不加 newline=""
with open("bad_csv.csv", mode="w", encoding='utf-8-sig') as f:
writer = csv.writer(f)
writer.writerow(["姓名", "年龄", "城市"])
writer.writerow(["张三", "25", "北京"])
writer.writerow(["李四", "30", "上海"])
# 正确写法:加上 newline=""
with open("good_csv.csv", mode="w", encoding='utf-8-sig', newline="") as f:
writer = csv.writer(f)
writer.writerow(["姓名", "年龄", "城市"])
writer.writerow(["张三", "25", "北京"])
writer.writerow(["李四", "30", "上海"])
运行结果对比:
bad_csv.csv(Windows 上):可能出现双重换行符\r\r\n,导致在某些编辑器或 Excel 中显示空白行good_csv.csv:格式正确,每行以\r\n结束(Windows 标准)
我的踩坑实录:Excel 打开 CSV 显示异常
我第一次处理 CSV 导出功能时,用户反馈在 Excel 中打开文件总是显示奇怪的空白行。排查过程如下:
- 现象:在 Python 中生成的 CSV 文件,用文本编辑器查看正常,但用 Excel 打开时每隔一行就有一个空白行
- 排查:用十六进制编辑器查看文件,发现行结束符是
\r\r\n而不是标准的\r\n - 原因:Windows 上的 Python 默认将
\n转换为\r\n,而csv.writer已经写入了\r\n,导致双重转换 - 解决:在
open()函数中添加newline=""参数,禁用 Python 的自动换行符转换
根据 Python 的文件 I/O 机制,建议在读写 CSV、JSON 等需要精确控制换行符的文本文件时,都显式指定
newline=""参数,避免平台差异带来的格式问题。
推荐写法
import csv
# 最佳实践:同时指定编码和 newline 参数
with open("output.csv", mode="w", encoding='utf-8-sig', newline="") as f:
writer = csv.writer(f)
# 写入表头
writer.writerow(["列1", "列2", "列3"])
# 写入数据行
writer.writerows([
["数据1", "数据2", "数据3"],
["数据4", "数据5", "数据6"]
])
关键点:
encoding='utf-8-sig':添加 BOM 头,确保 Excel 正确识别 UTF-8 编码newline="":禁用 Python 的自动换行符转换,让csv.writer完全控制行结束符- 这种写法在 Windows、macOS、Linux 上都能生成一致的 CSV 文件格式
总结
通过前面的讲解,我们明确了 CSV 文件处理中的几个关键要点:
1. newline="" 参数的核心作用
- 禁止 Python 自动处理换行符:让
csv模块完全控制行尾格式 - 避免多余空行:防止在不同操作系统上出现额外的空行
- 跨平台兼容性:确保 CSV 文件在 Windows、macOS、Linux 上都能正确显示
2. 编码选择的重要性
utf-8-sig:写入时使用,添加 BOM 头,确保 Excel 能正确识别中文utf-8:读取时使用,避免重复 BOM 导致解析错误
3. 完整的 CSV 写入示例
import csv
# 写入 CSV 文件
with open("students.csv", mode="w", encoding="utf-8-sig", newline="") as f:
writer = csv.writer(f)
# 写入表头
header = ["学号", "姓名", "年龄", "班级"]
writer.writerow(header)
# 写入数据行
data = [
["2025006", "小宇", 17, "高一3班"],
["2025007", "小琪", 18, "高一4班"]
]
writer.writerows(data)
print("CSV 文件写入成功!")
# 读取 CSV 文件
with open("students.csv", mode="r", encoding="utf-8", newline="") as f:
reader = csv.reader(f)
for row in reader:
print(row)
4. 常见错误避免
- 缩进错误:确保
with语句块内的代码正确缩进 - 变量名不一致:读取时使用的变量名要与写入时一致
- 编码不匹配:写入用
utf-8-sig,读取用utf-8
5. 最佳实践
- 始终使用
newline=""参数 - 写入时使用
utf-8-sig编码 - 读取时使用
utf-8编码 - 使用有意义的变量名
- 添加适当的注释和错误处理
掌握这些要点后,你就能轻松处理各种 CSV 文件,避免常见的格式问题和兼容性问题。
发生错误的原因
这个错误的核心在于 Python 代码的缩进不一致。让我们仔细分析你的代码:
with open("simple_CSV.csv", mode="w", encoding='utf-8-sig', newline="") as f:
...
with open("simple_CSV.csv", mode="r", encoding='utf-8', newline="") as f:
...
问题分析
-
缩进层级混乱:
- 第一个
with语句后面应该跟一个缩进块 - 第二个
with语句被多缩进了两个空格(with前面有两个空格) - 这导致 Python 解释器无法确定第二个
with语句的缩进层级
- 第一个
-
Python 的缩进规则:
- Python 使用缩进来定义代码块结构
- 同一层级的语句必须有相同的缩进量
- 通常使用 4 个空格作为标准缩进(PEP 8 规范)
-
错误信息解读:
IndentationError: unindent does not match any outer indentation levelunindent:表示"取消缩进"或"减少缩进"- 这个错误说明 Python 遇到了一个缩进减少,但这个减少没有匹配到任何外层的缩进级别
正确的代码结构
# 正确写法:两个 with 语句在同一缩进层级
with open("simple_CSV.csv", mode="w", encoding='utf-8-sig', newline="") as f:
# 写入操作
writer = csv.writer(f)
writer.writerow(["姓名", "年龄", "城市"])
writer.writerow(["张三", "25", "北京"])
with open("simple_CSV.csv", mode="r", encoding='utf-8', newline="") as f:
# 读取操作
reader = csv.reader(f)
for row in reader:
print(row)
如何避免这类错误
- 使用代码编辑器:推荐使用 VS Code、PyCharm 等 IDE,它们会自动处理缩进
- 开启显示空白字符:在编辑器中显示空格和制表符
- 遵循 PEP 8:统一使用 4 个空格缩进,不要混用空格和制表符
- 使用格式化工具:如
black、autopep8自动格式化代码
快速检查方法
如果你不确定缩进是否正确,可以:
- 复制代码到 Python 交互环境
- 使用编辑器的"格式化文档"功能
- 运行
python -m py_compile your_script.py检查语法
记住:在 Python 中,缩进不是风格问题,而是语法要求。正确的缩进是代码正常运行的前提。
4. 正确写法:保持一致的缩进与编码规范
下面是一个完整的、符合Python编码规范的CSV读写示例。请注意代码中的缩进一致性、编码设置和newline=""参数的使用:
import csv
# 示例数据:包含中英文混合内容
csv_content = [
["姓名", "年龄", "城市", "职业"],
["张三", 28, "北京", "软件工程师"],
["李四", 32, "上海", "数据分析师"],
["John Doe", 35, "New York", "Product Manager"],
["王五", 29, "深圳", "前端开发工程师"]
]
# 1. 写入CSV文件(使用utf-8-sig编码解决Excel中文乱码问题)
with open("employees.csv", mode="w", encoding='utf-8-sig', newline="") as f:
writer_csv = csv.writer(f)
writer_csv.writerows(csv_content)
print("✅ CSV文件写入成功!")
# 2. 读取并验证写入的内容
print("\n📋 读取CSV文件内容:")
with open("employees.csv", mode="r", encoding='utf-8', newline="") as f:
reader_rw = csv.reader(f)
for row in reader_rw:
print(row)
关键要点解析:
-
缩进一致性:所有代码块都使用4个空格的缩进,这是Python官方的PEP 8编码规范要求。
-
编码选择:
- 写入时使用
utf-8-sig:添加BOM(字节顺序标记),确保Excel能正确识别中文 - 读取时使用
utf-8:兼容性更好,避免BOM干扰
- 写入时使用
-
newline=""参数:- 写入和读取时都设置
newline="",防止跨平台换行符问题 - 避免Windows/Linux/macOS系统间的兼容性问题
- 写入和读取时都设置
-
文件操作最佳实践:
- 使用
with语句自动管理文件资源 - 清晰的变量命名(
writer_csv、reader_rw) - 添加适当的输出提示,便于调试
- 使用
运行结果示例:
✅ CSV文件写入成功!
📋 读取CSV文件内容:
['姓名', '年龄', '城市', '职业']
['张三', '28', '北京', '软件工程师']
['李四', '32', '上海', '数据分析师']
['John Doe', '35', 'New York', 'Product Manager']
['王五', '29', '深圳', '前端开发工程师']
这个示例展示了从数据准备、文件写入到读取验证的完整流程,每个步骤都有明确的注释说明。
额外提示
你还应该注意这两处问题:
for readCSV in reader_csv:应该是for readCSV in reader_rw:,因为你读的是reader_rwprint(reader_csv)也应改成print(readCSV),否则每次会打印错误变量
所以主要答案是:因为你的第二个 with 语句缩进不对,导致 Python 看不懂代码块结构。
with open("simple_CSV.csv",mode="w",encoding='utf-8-sig',newline="") as f:
writer_csv = csv.writer(f)
header_writer =["学号", "姓名", "年龄", "班级"]
#写入csv表头
csv_content = [ ["2025006", "小宇", 17, "高一3班"],
["2025007", "小琪", 18, "高一4班"]]
writer_csv.writerow(header_writer)#表头只有一行,所以这里只需要调用一次单行写入就可以了
#接下来写入内容,由于是写入多行,所以需要执行多行写入
writer_csv.writerows(csv_content)
print("文件写入成功")
#写下来读取一下
with open("simple_CSV.csv",mode="r",encoding='utf-8',newline="") as f:
reader_rw = csv.reader(f)
for readCSV in reader_csv:
print(readCSV)
报错为:---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
Cell In[20], line 15
13 with open(“simple_CSV.csv”,mode=“r”,encoding=‘utf-8’,newline=“”) as f:
14 reader_rw = csv.reader(f)
—> 15 for readCSV in reader_csv:
16 print(readCSV)
ValueError: I/O operation on closed file.
with open("simple_CSV.csv",mode="w",encoding='utf-8-sig',newline="") as f:
writer_csv = csv.writer(f)
header_writer =["学号", "姓名", "年龄", "班级"]
#写入csv表头
csv_content = [ ["2025006", "小宇", 17, "高一3班"],
["2025007", "小琪", 18, "高一4班"]]
writer_csv.writerow(header_writer)#表头只有一行,所以这里只需要调用一次单行写入就可以了
#接下来写入内容,由于是写入多行,所以需要执行多行写入
writer_csv.writerows(csv_content)
print("文件写入成功")
#写下来读取一下
with open("simple_CSV.csv",mode="r",encoding='utf-8',newline="") as f:
reader_rw = csv.reader(f)
for readCSV in reader_rw:
print(readCSV)
输出为:文件写入成功
[‘\ufeff学号’, ‘姓名’, ‘年龄’, ‘班级’]
[‘2025006’, ‘小宇’, ‘17’, ‘高一3班’]
[‘2025007’, ‘小琪’, ‘18’, ‘高一4班’]
但是打开文件为什么看到文件没有被实际修改?## 为什么看起来文件内容没改?
你的代码已经成功写入并读取了新数据:
- 控制台输出显示新的 CSV 行:
['\ufeff学号', '姓名', '年龄', '班级']['2025006', '小宇', '17', '高一4班']
- 说明
open(..., mode="w", ...)已经成功写入到一个simple_CSV.csv文件中了
可能原因
1. 你查看的不是同一个文件
with open("simple_CSV.csv", ...) 使用的是相对路径,它会基于当前 Python 进程的工作目录 os.getcwd(),而不一定是你当前 notebook 文件所在的文件夹。
所以你可能写入的是:
d:\python_code_test\simple_CSV.csv
但你查看的是:
- simple_CSV.csv
2. 编辑器没有刷新文件内容
即使文件被外部更改,VS Code 编辑器窗口也可能没有自动刷新。你需要:
- 重新打开该 CSV 文件
- 或点击“刷新”
- 或运行
os.getcwd()检查工作目录
如何确认
在 notebook 里加这段:
import os
print(os.getcwd())
如果你想确保写到指定文件夹,改成绝对路径:
with open(r"d:\python_code_test\CSV_learn\simple_CSV.csv", mode="w", encoding="utf-8-sig", newline="") as f:
结论
你写入的文件已经修改了,但你看到的文件内容可能是:
- 另一个路径下的
simple_CSV.csv - 或者当前打开的文件视图还没刷新
所以主要不是写入失败,而是文件路径/视图问题。
接下来是如何按照字典的形式来写入
之前的写入是将数据封装在列表之中,每一个数据单元都是一个列表
header_writer =["学号", "姓名", "年龄", "班级"]
#写入csv表头
csv_content = [ ["2025006", "小宇", 17, "高一3班"],
["2025007", "小琪", 18, "高一4班"]]
with open("simple_CSV.csv",mode="w",encoding='utf-8-sig',newline="") as f:
writer_obj = csv.DictWriter(f,fieldnames=header_writer)
writer_obj.writeheader()
writer_obj.writerows(csv_content)
print(f"以字典的形式写入成功")
with open("simple_CSV.csv",mode="r",encoding='utf-8',newline="") as f:
reader_rw = csv.DictReader(f)
for readCSV in reader_rw:
print(readCSV)
错误原因
你这段代码用的是 csv.DictWriter:
writer_obj = csv.DictWriter(f, fieldnames=header_writer)
writer_obj.writeheader()
writer_obj.writerows(csv_content)
但是 writerows 传进去的 csv_content 是一个由「列表」组成的列表:
[
["2025006", "小宇", 17, "高一3班"],
["2025007", "小琪", 18, "高一4班"]
]
DictWriter 需要的是「字典」行对象,每一行应该像这样:
{"学号": "2025006", "姓名": "小宇", "年龄": 17, "班级": "高一3班"}
所以报错的原因是:
DictWriter.writerows内部要访问每行的.keys()- 但你传入的是
list,list没有.keys() - 因此出现
AttributeError: 'list' object has no attribute 'keys'
解决方法
方法 1:用 csv.writer
如果你已经有列表格式的数据,就直接用普通 csv.writer:
with open("simple_CSV.csv", mode="w", encoding="utf-8-sig", newline="") as f:
writer_csv = csv.writer(f)
header_writer = ["学号", "姓名", "年龄", "班级"]
csv_content = [
["2025006", "小宇", 17, "高一3班"],
["2025007", "小琪", 18, "高一4班"]
]
writer_csv.writerow(header_writer)
writer_csv.writerows(csv_content)
方法 2:用 csv.DictWriter,改成字典数据
如果你要用 DictWriter,数据要改成字典:
header_writer = ["学号", "姓名", "年龄", "班级"]
csv_content = [
{"学号": "2025006", "姓名": "小宇", "年龄": 17, "班级": "高一3班"},
{"学号": "2025007", "姓名": "小琪", "年龄": 18, "班级": "高一4班"}
]
with open("simple_CSV.csv", mode="w", encoding="utf-8-sig", newline="") as f:
writer_obj = csv.DictWriter(f, fieldnames=header_writer)
writer_obj.writeheader()
writer_obj.writerows(csv_content)
结论
错误是因为你用 DictWriter 写了「列表行」,而它需要「字典行」。只要改成 csv.writer,或把数据转成字典,就能正常写入。
header_writer = ["学号", "姓名", "年龄", "班级"]
#写入csv表头
csv_content = [
{"学号": "2025006", "姓名": "小宇", "年龄": 17, "班级": "高一3班"},
{"学号": "2025007", "姓名": "小琪", "年龄": 18, "班级": "高一4班"}
]
with open("simple_CSV.csv",mode="w",encoding='utf-8-sig',newline="") as f:
writer_obj = csv.DictWriter(f,fieldnames=header_writer)
writer_obj.writeheader()
writer_obj.writerows(csv_content)
print(f"以字典的形式写入成功")
with open("simple_CSV.csv",mode="r",encoding='utf-8',newline="") as f:
reader_rw = csv.DictReader(f)
for readCSV in reader_rw:
print(readCSV)
输出为:
以字典的形式写入成功
{‘\ufeff学号’: ‘2025006’, ‘姓名’: ‘小宇’, ‘年龄’: ‘17’, ‘班级’: ‘高一3班’}
{‘\ufeff学号’: ‘2025007’, ‘姓名’: ‘小琪’, ‘年龄’: ‘18’, ‘班级’: ‘高一4班’}
csv在数据清洗中非常有用
接下来是自定义分隔符:
假设以 \t作
🎯 总结与进阶建议
通过本文的学习,你已经掌握了 Python 处理 CSV 文件的核心技能。让我们回顾一下关键要点:
📋 核心知识点回顾
- 基础读取:使用
csv.reader进行简单读取,或使用csv.DictReader按列名访问数据 - 正确写入:理解
csv.writer与csv.DictWriter的区别,避免数据类型不匹配的错误 - 编码处理:使用
utf-8-sig编码解决 Excel 打开时的乱码问题 - 换行符处理:
newline=""参数的重要性,避免写入时产生空行 - 分隔符定制:使用
delimiter参数自定义字段分隔符(如制表符\t)
🔧 常见问题解决方案
| 问题 | 原因 | 解决方案 |
|---|---|---|
| Excel 打开乱码 | 编码问题 | 使用 encoding='utf-8-sig' |
| 写入后有空行 | 换行符问题 | 添加 newline="" 参数 |
| DictWriter 报错 | 数据类型不匹配 | 确保传入字典数据或改用 csv.writer |
| 读取分隔符错误 | 读写分隔符不一致 | 读写时使用相同的 delimiter 参数 |
🚀 进阶学习建议
- 大数据处理:对于大型 CSV 文件,考虑使用
pandas库的read_csv()和to_csv()方法 - 性能优化:使用
chunksize参数分块读取大文件,避免内存溢出 - 数据验证:结合
pydantic或marshmallow进行数据验证和类型转换 - 异步处理:使用
aiofiles进行异步 CSV 文件操作 - 数据库集成:学习使用
sqlalchemy将 CSV 数据导入数据库
💡 最佳实践清单
✅ 编码规范:始终明确指定文件编码,推荐 utf-8-sig
✅ 换行处理:写入时使用 newline="" 参数
✅ 错误处理:使用 try-except 包装文件操作
✅ 资源管理:使用 with 语句确保文件正确关闭
✅ 数据验证:写入前验证数据类型和格式
✅ 路径安全:使用 os.path 处理文件路径,避免硬编码
📚 推荐学习资源
- 官方文档:Python csv 模块文档
- 进阶库:pandas 数据处理
- 实战项目:CSV 数据清洗实战
- 性能优化:处理大型 CSV 文件的技巧
🌟 写在最后
CSV 作为最常用的数据交换格式,掌握其处理技巧是每个 Python 开发者的必备技能。从基础的读写操作到高级的性能优化,希望本文能为你提供全面的指导。记住,良好的编码习惯和错误处理机制比复杂的技巧更重要。
实践是最好的老师——尝试处理真实的数据集,解决实际遇到的问题,你的技能会得到真正的提升。如果在学习过程中遇到任何问题,欢迎在评论区留言讨论!
更多推荐
所有评论(0)