Python3 csv 模块及应用

🎉摘要:本文详细讲解 CSV 文件格式与规范,并介绍 Python 内置 csv 模块的使用方法,包括 reader、writer、DictReader、DictWriter 等常用函数,演示列表 / 字典读写 csv、追加数据、处理特殊字符等操作,附学生成绩管理系统实战案例,零基础也能快速掌握 Python 处理 CSV 文件技巧。

CSV 文件又称为逗号分隔文件,该文件中每行代表一行数据,每行数据中使用逗号分隔成多列。就像这样:

id,name,age,sex,email
1,张三,25,男,zhangsan@qq.com
2,李四,30,女,lisi@qq.com
3,王五,28,男,wangwu@qq.com
4,赵六,22,女,zhaoliu@qq.com
5,钱七,35,男,qianqi@qq.com

注意,文件后缀为“.csv”,我们可以使用 Word 软件直接打开,下面是通过 WPS 打开的效果图:

可以直接进行编辑,但是不能添加格式和应用 Excel 公式,除非另存为 Excel 文档。

更多 CSV 文件规范信息请参考 https://www.rfc-editor.org/rfc/rfc4180 文档。

在 Python 中,内置了 csv 模块,专门用来读写 CSV 文件。csv 模块自动处理逗号、引号、换行符等特殊字符,而且支持列表 / 字典两种读写方式,操作方便。

常用方法

下面列举使用 csv 模块时,常被用到的方法:

  • csv.reader()   按列表读取 CSV 文件,即每行返回一个列表,如 ['张三', '22', '北京'],要访问指定列的数据,仅能通过下标访问,当数据位置发生变化,需要同步修改代码。

  • csv.writer()   按列表写入 CSV 文件,即数据使用二维列表存储,然后将整个二位列表传递给 writer 方法。

  • csv.DictReader()   按字典读取 CSV(表头为 key)

  • csv.DictWriter()   按字典写入 CSV(自动写表头)

  • csv.writerow()   写入一行数据

  • csv.writerows()   写入多行数据

常用参数:

  • delimiter=',':分隔符(默认逗号)

  • quotechar='"':引号字符

  • encoding='utf-8':编码(中文必须指定)

  • newline='':读写时必须加,防止空行(Windows 必加)

实战示例

列表方式操作 csv

本示例将演示 reader() 和 writer() 方法的使用,通过列表的方式将数据写入到 csv 文件,同时也是用列表的方式从 csv 读取数据。例如:

import csv

# 准备写入数据
data = [
    ["姓名", "年龄", "城市"],  # 表头
    ["张三", 22, "北京"],
    ["李四", 25, "上海"],
    ["王五", 23, "深圳"]
]

# 写入数据
# 使用 with open 方式,设置 newline='' 防止多余空行
with open("student.csv", "w", encoding="utf-8", newline="") as f:
    writer = csv.writer(f) # 创建 writer 对象
    writer.writerows(data) # 一次性写入多行
    print("列表写入 CSV 完成!")

# 读取数据
with open("student.csv", "r", encoding="utf-8") as f:
    reader = csv.reader(f) # 创建 reader 对象
    for row in reader: # 逐行读取
        print(row)

运行结果:

列表写入 CSV 完成!
['姓名', '年龄', '城市']
['张三', '22', '北京']
['李四', '25', '上海']
['王五', '23', '深圳']

注意,如果你要获取年龄,则能通过下标获取,如 row[1],如果 csv 文件内容变化了,“年龄”和“城市”列换了位置,就需要修改代码,改为 row[2],不方便。有没有一种方式,即使数据位置发生变化也不需要修改代码呢,答案是有的,使用字典方式操作 csv。

字典方式操作 csv

上面示例介绍了通过列表访问数据的缺点,通过字典方式可以解决这个问题。可以通过 DictWriter() 和 DictReader() 来实现。例如:

import csv

# 准备数据
# 表头
headers = ["name", "age", "city"]

# 数据(字典列表)
rows = [
    {"name": "小明", "age": 20, "city": "广州"},
    {"name": "小红", "age": 21, "city": "杭州"},
]

# 数据写入csv
with open("user.csv", "w", encoding="utf-8", newline="") as f:
    # 创建 DictWriter 对象,指定表头字段
    writer = csv.DictWriter(f, fieldnames=headers)
    writer.writeheader() # 自动写入表头
    writer.writerows(rows) # 写入多行字典数据
    print("字典写入 CSV 完成!")

# 读取csv数据
with open("user.csv", "r", encoding="utf-8") as f:
    reader = csv.DictReader(f)
    for row in reader:
        # 直接通过字段名取值
        print(f"姓名:{row['name']},年龄:{row['age']},城市:{row['city']}")

运行结果:

字典写入 CSV 完成!
姓名:小明,年龄:20,城市:广州
姓名:小红,年龄:21,城市:杭州

注意,通过该种方式,数据列位置顺序变了也能正常访问。不再使用下标方式,而是通过头名称进行访问。

追加数据到 csv

如果我们要对一个已经存在的 csv 文件写入数据,可以开启文件追加写模型(),例如:

import csv

new_row = ["赵六", 26, "成都"]

with open("student.csv", "a", encoding="utf-8", newline="") as f:
    writer = csv.writer(f)
    writer.writerow(new_row)

print("追加成功!")

注意,关于文件写入操作可以参考“Python3 文件 I/O”章节。

读取带特殊符号的 csv

csv 文件就是一个普通的文本文件,只是内部的数据通过逗号进行分割。如果某项数据中原本就包含逗号呢!直接进行读取就会出现错误,好在 csv 模块会帮助我们自动解决。例如:

import csv

data = [
    ["产品", "描述"],
    ["手机", "6.7英寸,黑色,全网通"], # 包含逗号
    ["电脑", '16G内存"游戏本'] # 包含引号
]

with open("product.csv", "w", encoding="utf-8", newline="") as f:
    writer = csv.writer(f)
    writer.writerows(data)
    print("特殊字符写入成功!")

with open("product.csv", "r", encoding="utf-8") as f:
    for row in csv.reader(f):
        print(row)

执行代码,读取时完全正常解析:

特殊字符写入成功!
['产品', '描述']
['手机', '6.7英寸,黑色,全网通']
['电脑', '16G内存"游戏本']

综合实战

如果你在没有学习数据库知识之前,想做一个可以存储简单数据的学生成绩管理系统该怎么办?最简单的办法就是通过文件保存数据。如果保存为普通的文件,数据操作较麻烦,需要自己读取文件数据,然后自己解析数据格式。

为了能够更简单的保存数据、查询数据,使用 csv 文件是一个不错的选择(当然,你也可以使用 JSON 文件)。

下面示例将演示如何通过 csv 文件来保存学生成绩管理系统的数据,主要功能如下:

  1. 写入学生成绩表

  2. 读取成绩并计算平均分

  3. 筛选出及格学生

  4. 生成新的成绩报告 CSV

完整代码:

import csv

def write_scores():
    """
    写入成绩数据
    """
    headers = ["id", "name", "score"]
    students = [
        {"id": 1, "name": "张三", "score": 88},
        {"id": 2, "name": "李四", "score": 59},
        {"id": 3, "name": "王五", "score": 76},
        {"id": 4, "name": "赵六", "score": 92},
    ]
    with open("scores.csv", "w", encoding="utf-8", newline="") as f:
        writer = csv.DictWriter(f, fieldnames=headers)
        writer.writeheader()
        writer.writerows(students)
    print("成绩数据已写入")

def read_and_calculate():
    """
    读取数据并计算平均分、筛选及格名单
    """
    total = 0
    count = 0
    pass_students = []

    with open("scores.csv", "r", encoding="utf-8") as f:
        reader = csv.DictReader(f)
        for row in reader:
            score = int(row["score"])
            total += score # 总成绩
            count += 1
            if score >= 60:
                pass_students.append(row) # 及格的学生

    avg = total / count # 计算平均分
    print(f"\n平均分:{avg:.2f}")
    print(f"及格人数:{len(pass_students)}")
    return pass_students

def write_pass_report(pass_list):
    """
    生成及格学生报告
    """
    headers = ["id", "name", "score"]
    with open("pass_report.csv", "w", encoding="utf-8", newline="") as f:
        writer = csv.DictWriter(f, fieldnames=headers)
        writer.writeheader()
        writer.writerows(pass_list)
    print("\n及格报告已生成:pass_report.csv")

if __name__ == "__main__":
    # 写入成绩数据
    write_scores()
    # 读取数据并计算平均分、筛选及格名单
    pass_list = read_and_calculate()
    # 生成及格学生报告
    write_pass_report(pass_list)

运行结果:

成绩数据已写入

平均分:78.75
及格人数:3

及格报告已生成:pass_report.csv

pass_report.csv 文件的内容如下:

id,name,score
1,张三,88
3,王五,76
4,赵六,92

更多关于 csv 模块的知识,请参考 https://docs.python.org/3/library/csv.html 文档。

  

说说我的看法
全部评论(
没有评论
关于
本网站专注于 Java、数据库(MySQL、Oracle)、Linux、软件架构及大数据等多领域技术知识分享。涵盖丰富的原创与精选技术文章,助力技术传播与交流。无论是技术新手渴望入门,还是资深开发者寻求进阶,这里都能为您提供深度见解与实用经验,让复杂编码变得轻松易懂,携手共赴技术提升新高度。如有侵权,请来信告知:hxstrive@outlook.com
其他应用
公众号