Python CSV 模块:读写 CSV 文件详解
CSV (Comma Separated Values,逗号分隔值) 是一种非常常见的数据存储和交换格式。 它以纯文本形式存储表格数据(数字和文本),易于阅读和处理,并且可以被各种软件程序支持。
CSV 文件的核心特点是:
- 分隔符: 使用特定的字符(例如逗号
,
)分隔每个字段。 - 行: 每一行代表一条数据记录。
- 字段: 每条记录包含多个字段。
- 可选标题行: 第一行通常是标题行,用于描述每个字段的含义。
- 引号处理: 如果字段中包含分隔符或特殊字符,则需要使用引号(通常是双引号
"
)将该字段括起来。
例如,一个简单的 CSV 文件可能如下所示:
Name,Age,City
Alice,30,New York
Bob,25,London
Charlie,35,Paris
在这个例子中,逗号,
是分隔符,第一行是标题行,后面每一行代表一个人的姓名、年龄和城市信息。
Python 提供了一个内置的 csv
模块,专门用于处理 CSV 文件的读取和写入操作。 这个模块使得处理 CSV 数据变得非常简单方便。
1. 为什么要使用 CSV 模块?
虽然你可以使用字符串操作来手动解析 CSV 文件,但是 csv
模块提供了以下优势:
- 简化代码: 它封装了 CSV 文件的解析逻辑,使你无需编写复杂的字符串处理代码。
- 处理引号和转义: 它可以正确处理包含引号和转义字符的字段。
- 支持多种分隔符: 它允许你指定不同的分隔符和引号字符,以适应不同的 CSV 文件格式。
- 自动类型转换: 虽然
csv
模块返回的是字符串,但你可以方便地将这些字符串转换为其他数据类型(例如整数、浮点数)。
2. 读取 CSV 文件
csv.reader()
函数是读取 CSV 文件的核心。 它接受一个文件对象作为输入,并返回一个 reader 对象,你可以使用该对象逐行迭代 CSV 文件。
2.1 csv.reader()
函数的参数
csv.reader(csvfile, delimiter=',', quotechar='"', **fmtparams)
csvfile
: 一个可迭代的对象,通常是一个打开的文本文件对象。 重要: 打开文件时,建议使用newline=''
参数,以避免由于不同平台的换行符差异而导致的问题。delimiter
: 用于分隔字段的字符,默认为逗号,
。quotechar
: 用于包围包含分隔符的字段的字符,默认为双引号"
。**fmtparams
: 其他可选的格式化参数,例如skipinitialspace
(忽略分隔符后的空格)和strict
(在遇到错误的 CSV 行时引发异常)。
2.2 示例:读取简单的 CSV 文件
假设我们有一个名为 students.csv
的文件,内容如下:
Name,Major,GPA
Alice,Computer Science,3.8
Bob,Engineering,3.5
Charlie,Mathematics,3.9
以下代码演示如何使用 csv.reader()
读取该文件:
import csv
try:
with open('students.csv', 'r', newline='', encoding='utf-8') as csvfile:
reader = csv.reader(csvfile)
for row in reader:
print(row)
except FileNotFoundError:
print("文件 'students.csv' 未找到。")
except Exception as e:
print(f"读取 CSV 时出错: {e}")
代码解释:
import csv
: 导入csv
模块。with open('students.csv', 'r', newline='', encoding='utf-8') as csvfile:
: 使用with
语句打开文件,确保文件在使用后自动关闭。'r'
表示以只读模式打开文件。newline=''
防止出现换行符问题。encoding='utf-8'
指定文件编码为 UTF-8,可以正确处理包含中文等非 ASCII 字符的文件。reader = csv.reader(csvfile)
: 创建一个reader
对象,用于读取 CSV 文件。for row in reader:
: 迭代reader
对象,每次迭代返回一行数据,以列表的形式存储在row
变量中。print(row)
: 打印每一行数据。
输出:
['Name', 'Major', 'GPA']
['Alice', 'Computer Science', '3.8']
['Bob', 'Engineering', '3.5']
['Charlie', 'Mathematics', '3.9']
2.3 跳过标题行
通常,CSV 文件的第一行是标题行。 如果你不想处理标题行,可以使用 next()
函数跳过它:
import csv
try:
with open('students.csv', 'r', newline='', encoding='utf-8') as csvfile:
reader = csv.reader(csvfile)
header = next(reader) # 读取并跳过标题行
print("标题:", header)
for row in reader:
print(row)
except FileNotFoundError:
print("文件 'students.csv' 未找到。")
except Exception as e:
print(f"读取 CSV 时出错: {e}")
输出:
标题: ['Name', 'Major', 'GPA']
['Alice', 'Computer Science', '3.8']
['Bob', 'Engineering', '3.5']
['Charlie', 'Mathematics', 3.9']
2.4 使用不同的分隔符和引号字符
如果你的 CSV 文件使用不同的分隔符或引号字符,你可以在 csv.reader()
函数中指定它们。 例如,如果你的 CSV 文件使用分号;
作为分隔符,并且使用尖括号<>
作为引号字符,你可以这样读取它:
import csv
try:
with open('data.csv', 'r', newline='', encoding='utf-8') as csvfile:
reader = csv.reader(csvfile, delimiter=';', quotechar='<')
for row in reader:
print(row)
except FileNotFoundError:
print("文件 'data.csv' 未找到。")
except Exception as e:
print(f"读取 CSV 时出错: {e}")
假设 data.csv
包含以下内容:
Name;Address;Phone
John;<123 Main St; Anytown>;555-1234
Jane;<456 Oak Ave; Somecity>;555-5678
输出将会是:
['Name', 'Address', 'Phone']
['John', '123 Main St; Anytown', '555-1234']
['Jane', '456 Oak Ave; Somecity', '555-5678']
3. 写入 CSV 文件
csv.writer()
函数用于创建 writer 对象,你可以使用该对象将数据写入 CSV 文件。
3.1 csv.writer()
函数的参数
csv.writer(csvfile, delimiter=',', quotechar='"', quoting=csv.QUOTE_MINIMAL, **fmtparams)
csvfile
: 一个可迭代的对象,通常是一个打开的文本文件对象。 重要: 打开文件时,建议使用newline=''
参数。delimiter
: 用于分隔字段的字符,默认为逗号,
。quotechar
: 用于包围包含分隔符的字段的字符,默认为双引号"
。quoting
: 一个控制何时使用引号的常量。 常用的值包括:csv.QUOTE_ALL
: 所有字段都用引号括起来。csv.QUOTE_MINIMAL
: 仅在字段包含分隔符、引号字符或特殊字符时才使用引号。 这是默认值。csv.QUOTE_NONNUMERIC
: 所有非数字字段都用引号括起来。csv.QUOTE_NONE
: 永远不使用引号。 如果字段中包含分隔符,写入时会引发错误。
**fmtparams
: 其他可选的格式化参数。
3.2 写入数据
csv.writer
对象提供了以下两个主要方法来写入数据:
writerow(row)
: 将一行数据写入 CSV 文件。row
必须是一个可迭代的对象(例如列表或元组)。writerows(rows)
: 将多行数据写入 CSV 文件。rows
必须是一个可迭代的对象,其中每个元素都是一行数据。
3.3 示例:写入 CSV 文件
以下代码演示如何使用 csv.writer()
创建一个包含学生信息的 CSV 文件:
import csv
header = ['Name', 'Major', 'GPA']
data = [
['Alice', 'Computer Science', 3.8],
['Bob', 'Engineering', 3.5],
['Charlie', 'Mathematics', 3.9]
]
try:
with open('students_output.csv', 'w', newline='', encoding='utf-8') as csvfile:
writer = csv.writer(csvfile)
# 写入标题行
writer.writerow(header)
# 写入数据行
writer.writerows(data)
print("文件 'students_output.csv' 写入成功。")
except IOError as e:
print(f"写入 CSV 时出错: {e}")
代码解释:
import csv
: 导入csv
模块。header = ['Name', 'Major', 'GPA']
: 定义标题行。data = [...]
: 定义数据行。with open('students_output.csv', 'w', newline='', encoding='utf-8') as csvfile:
: 以写入模式'w'
打开文件。 如果文件不存在,则创建该文件。 如果文件已存在,则覆盖该文件。writer = csv.writer(csvfile)
: 创建一个writer
对象。writer.writerow(header)
: 写入标题行。writer.writerows(data)
: 写入数据行。
输出(students_output.csv):
Name,Major,GPA
Alice,Computer Science,3.8
Bob,Engineering,3.5
Charlie,Mathematics,3.9
3.4 使用不同的分隔符和引号
import csv
header = ['Name', 'Address', 'Phone']
data = [
['John', '123 Main St; Anytown', '555-1234'],
['Jane', '456 Oak Ave; Somecity', '555-5678']
]
try:
with open('contacts.csv', 'w', newline='', encoding='utf-8') as csvfile:
writer = csv.writer(csvfile, delimiter=';', quotechar='"', quoting=csv.QUOTE_MINIMAL)
writer.writerow(header)
writer.writerows(data)
print("文件 'contacts.csv' 写入成功。")
except IOError as e:
print(f"写入 CSV 时出错: {e}")
在这个例子中,分隔符设置为;
,引号字符设置为"
。 quoting=csv.QUOTE_MINIMAL
确保只有包含分隔符的字段才会被引号括起来。
输出 (contacts.csv):
Name;Address;Phone
John;"123 Main St; Anytown";555-1234
Jane;"456 Oak Ave; Somecity";555-5678
4. csv.DictReader
和 csv.DictWriter
除了 csv.reader
和 csv.writer
之外,csv
模块还提供了 csv.DictReader
和 csv.DictWriter
类,它们可以将 CSV 文件中的每一行数据转换为字典,从而更方便地访问数据。
4.1 csv.DictReader
csv.DictReader
的工作方式与 csv.reader
类似,但它将每一行数据转换为一个字典,其中字典的键是标题行中的字段名。
import csv
try:
with open('students.csv', 'r', newline='', encoding='utf-8') as csvfile:
reader = csv.DictReader(csvfile)
for row in reader:
print(row['Name'], row['Major'], row['GPA'])
except FileNotFoundError:
print("文件 'students.csv' 未找到。")
except Exception as e:
print(f"读取 CSV 时出错: {e}")
输出:
Alice Computer Science 3.8
Bob Engineering 3.5
Charlie Mathematics 3.9
4.2 csv.DictWriter
csv.DictWriter
的工作方式与 csv.writer
类似,但它接受字典形式的数据作为输入,并将其写入 CSV 文件。
import csv
header = ['Name', 'Major', 'GPA']
data = [
{'Name': 'Alice', 'Major': 'Computer Science', 'GPA': 3.8},
{'Name': 'Bob', 'Major': 'Engineering', 'GPA': 3.5},
{'Name': 'Charlie', 'Major': 'Mathematics', 'GPA': 3.9}
]
try:
with open('students_dict_output.csv', 'w', newline='', encoding='utf-8') as csvfile:
writer = csv.DictWriter(csvfile, fieldnames=header)
# 写入标题行
writer.writeheader()
# 写入数据行
writer.writerows(data)
print("文件 'students_dict_output.csv' 写入成功。")
except IOError as e:
print(f"写入 CSV 时出错: {e}")
代码解释:
csv.DictWriter(csvfile, fieldnames=header)
: 创建DictWriter
对象,并指定字段名fieldnames
。fieldnames
必须是一个包含所有字段名的列表。writer.writeheader()
: 写入标题行。 此方法使用fieldnames
中的字段名作为标题。writer.writerows(data)
: 写入数据行。data
必须是一个字典列表,其中每个字典都包含与fieldnames
中字段名相对应的数据。
输出(students_dict_output.csv):
Name,Major,GPA
Alice,Computer Science,3.8
Bob,Engineering,3.5
Charlie,Mathematics,3.9
csv
模块是 Python 中处理 CSV 文件的强大工具。 它提供了简单易用的 API,可以方便地读取和写入 CSV 数据。 通过使用 csv.reader
、csv.writer
、csv.DictReader
和 csv.DictWriter
,你可以轻松地处理各种 CSV 文件格式,并将 CSV 数据集成到你的 Python 应用程序中。 记住始终使用 newline=''
打开文件,并根据需要指定分隔符、引号字符和编码方式,以确保你的代码能够正确处理各种 CSV 文件。