环境: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)

📝 本节要点总结

  1. 基础读取:使用 csv.reader 逐行读取,返回列表格式
  2. 字典读取:使用 csv.DictReader 按列名访问,代码更易读
  3. 性能考虑:小文件直接读取,大文件考虑批量处理
  4. 错误处理:使用 .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 中打开文件总是显示奇怪的空白行。排查过程如下:

  1. 现象:在 Python 中生成的 CSV 文件,用文本编辑器查看正常,但用 Excel 打开时每隔一行就有一个空白行
  2. 排查:用十六进制编辑器查看文件,发现行结束符是 \r\r\n 而不是标准的 \r\n
  3. 原因:Windows 上的 Python 默认将 \n 转换为 \r\n,而 csv.writer 已经写入了 \r\n,导致双重转换
  4. 解决:在 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. 常见错误避免

  1. 缩进错误:确保 with 语句块内的代码正确缩进
  2. 变量名不一致:读取时使用的变量名要与写入时一致
  3. 编码不匹配:写入用 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:
      ...

问题分析

  1. 缩进层级混乱

    • 第一个 with 语句后面应该跟一个缩进块
    • 第二个 with 语句被多缩进了两个空格( with 前面有两个空格)
    • 这导致 Python 解释器无法确定第二个 with 语句的缩进层级
  2. Python 的缩进规则

    • Python 使用缩进来定义代码块结构
    • 同一层级的语句必须有相同的缩进量
    • 通常使用 4 个空格作为标准缩进(PEP 8 规范)
  3. 错误信息解读

    IndentationError: unindent does not match any outer indentation level
    
    • unindent:表示"取消缩进"或"减少缩进"
    • 这个错误说明 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)

如何避免这类错误

  1. 使用代码编辑器:推荐使用 VS Code、PyCharm 等 IDE,它们会自动处理缩进
  2. 开启显示空白字符:在编辑器中显示空格和制表符
  3. 遵循 PEP 8:统一使用 4 个空格缩进,不要混用空格和制表符
  4. 使用格式化工具:如 blackautopep8 自动格式化代码

快速检查方法

如果你不确定缩进是否正确,可以:

  1. 复制代码到 Python 交互环境
  2. 使用编辑器的"格式化文档"功能
  3. 运行 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)

关键要点解析:

  1. 缩进一致性:所有代码块都使用4个空格的缩进,这是Python官方的PEP 8编码规范要求。

  2. 编码选择

    • 写入时使用utf-8-sig:添加BOM(字节顺序标记),确保Excel能正确识别中文
    • 读取时使用utf-8:兼容性更好,避免BOM干扰
  3. newline=""参数

    • 写入和读取时都设置newline="",防止跨平台换行符问题
    • 避免Windows/Linux/macOS系统间的兼容性问题
  4. 文件操作最佳实践

    • 使用with语句自动管理文件资源
    • 清晰的变量命名(writer_csvreader_rw
    • 添加适当的输出提示,便于调试

运行结果示例:

✅ CSV文件写入成功!

📋 读取CSV文件内容:
['姓名', '年龄', '城市', '职业']
['张三', '28', '北京', '软件工程师']
['李四', '32', '上海', '数据分析师']
['John Doe', '35', 'New York', 'Product Manager']
['王五', '29', '深圳', '前端开发工程师']

这个示例展示了从数据准备、文件写入到读取验证的完整流程,每个步骤都有明确的注释说明。

额外提示

你还应该注意这两处问题:

  • for readCSV in reader_csv: 应该是 for readCSV in reader_rw:,因为你读的是 reader_rw
  • print(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()
  • 但你传入的是 listlist 没有 .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 文件的核心技能。让我们回顾一下关键要点:

📋 核心知识点回顾

  1. 基础读取:使用 csv.reader 进行简单读取,或使用 csv.DictReader 按列名访问数据
  2. 正确写入:理解 csv.writercsv.DictWriter 的区别,避免数据类型不匹配的错误
  3. 编码处理:使用 utf-8-sig 编码解决 Excel 打开时的乱码问题
  4. 换行符处理newline="" 参数的重要性,避免写入时产生空行
  5. 分隔符定制:使用 delimiter 参数自定义字段分隔符(如制表符 \t

🔧 常见问题解决方案

问题 原因 解决方案
Excel 打开乱码 编码问题 使用 encoding='utf-8-sig'
写入后有空行 换行符问题 添加 newline="" 参数
DictWriter 报错 数据类型不匹配 确保传入字典数据或改用 csv.writer
读取分隔符错误 读写分隔符不一致 读写时使用相同的 delimiter 参数

🚀 进阶学习建议

  1. 大数据处理:对于大型 CSV 文件,考虑使用 pandas 库的 read_csv()to_csv() 方法
  2. 性能优化:使用 chunksize 参数分块读取大文件,避免内存溢出
  3. 数据验证:结合 pydanticmarshmallow 进行数据验证和类型转换
  4. 异步处理:使用 aiofiles 进行异步 CSV 文件操作
  5. 数据库集成:学习使用 sqlalchemy 将 CSV 数据导入数据库

💡 最佳实践清单

编码规范:始终明确指定文件编码,推荐 utf-8-sig
换行处理:写入时使用 newline="" 参数
错误处理:使用 try-except 包装文件操作
资源管理:使用 with 语句确保文件正确关闭
数据验证:写入前验证数据类型和格式
路径安全:使用 os.path 处理文件路径,避免硬编码

📚 推荐学习资源

  1. 官方文档Python csv 模块文档
  2. 进阶库pandas 数据处理
  3. 实战项目CSV 数据清洗实战
  4. 性能优化处理大型 CSV 文件的技巧

🌟 写在最后

CSV 作为最常用的数据交换格式,掌握其处理技巧是每个 Python 开发者的必备技能。从基础的读写操作到高级的性能优化,希望本文能为你提供全面的指导。记住,良好的编码习惯和错误处理机制比复杂的技巧更重要。

实践是最好的老师——尝试处理真实的数据集,解决实际遇到的问题,你的技能会得到真正的提升。如果在学习过程中遇到任何问题,欢迎在评论区留言讨论!


更多推荐