HOWTO · Python
在 Python 中读取带有标题的 CSV
了解如何在 Python 中读取带有标题的 CSV。
本页内容
Python 标准库中的 csv 模块可以逐行读取逗号分隔文件。CSV 文件通常会在第一行存放列名,后续各行存放记录。以下示例均假设文件采用这种布局;csv.reader 本身不会自动将第一行识别为表头。它会返回一个可迭代的行序列,每行都是由字符串组成的列表。
这些示例会自行创建小型输入文件,因此无需下载配套文件即可运行。处理实际文件时,请将临时文件设置替换为实际文件路径,并使用 newline="" 打开文件,同时选择适合该文件的编码。你也可以查看这个示例 邮件 CSV 文件。每个示例后面的输出展示了相应的运行结果。
在 Python 中读取带表头的 CSV 文件
将打开的文本文件传给 csv.reader,然后遍历返回的对象。循环会包含每一行,因此第一个打印出的列表就是列名所在的行。如果你想先查看原始记录,再单独处理表头,这种方式很有用。
运行以下示例:
本节中的代码以及显示的标签或输出仍为英文。
import csv
import tempfile
with tempfile.NamedTemporaryFile(mode="w", encoding="utf-8", newline="", delete=False) as source:
source.write("name,team\nAda,Research\nLin,Design\n")
path = source.name
with open(path, encoding="utf-8", newline="") as source:
rows = csv.reader(source)
for row in rows:
print(row)
['name', 'team']
['Ada', 'Research']
['Lin', 'Design']
读取器会按照 CSV 的引号规则解析字段;如果字段中带引号的逗号被当作普通分隔符,手动按逗号拆分每一行可能会得到错误结果。遍历文件只需顺序读取一遍,因此耗时会随输入规模线性增长。对于较大的文件,这种方式无需将所有行同时载入内存。
提取表头并分别处理数据行
对读取器调用内置的 next() 函数,取出第一行并将其保存为表头。之后读取器会从下一行继续,因此循环只需处理数据记录。这样可以将列名与数据值分开,而不必把整个文件载入列表。
运行以下示例:
本节中的代码以及显示的标签或输出仍为英文。
import csv
import tempfile
with tempfile.NamedTemporaryFile(mode="w", encoding="utf-8", newline="", delete=False) as source:
source.write("name,team\nAda,Research\nLin,Design\n")
path = source.name
with open(path, encoding="utf-8", newline="") as source:
rows = csv.reader(source)
header = next(rows)
print("Header:", ", ".join(header))
for row in rows:
print(dict(zip(header, row)))
Header: name, team
{'name': 'Ada', 'team': 'Research'}
{'name': 'Lin', 'team': 'Design'}
这里,zip 会将每个列名与对应字段配对,dict 则让你可以按名称访问这些配对结果。此方法假定文件有表头,并且每条记录中的字段顺序都与表头一致。如果文件可能没有任何行,请先检查是否读到了第一行,再将其用作表头;否则 next() 将没有行可返回。
使用不同的 delimiter 读取 CSV
默认分隔符是逗号。如果文件使用分号,请将 delimiter 参数传给 csv.reader,并使用输入文件中实际用于分隔字段的字符。读取器的行为不变,但表头仍需显式处理:按照惯例,第一行存放表头;csv.reader 不会将其识别为表头,因此本示例会先用 next() 取出这一行,再打印其余记录。
运行以下示例:
本节中的代码以及显示的标签或输出仍为英文。
import csv
import tempfile
with tempfile.NamedTemporaryFile(mode="w", encoding="utf-8", newline="", delete=False) as source:
source.write("name;team\nAda;Research\nLin;Design\n")
path = source.name
with open(path, encoding="utf-8", newline="") as source:
rows = csv.reader(source, delimiter=";")
header = next(rows)
print("Header:", ", ".join(header))
for row in rows:
print(", ".join(row))
Header: name, team
Ada, Research
Lin, Design
对于其他格式,请将 delimiter 设为文件实际使用的分隔符,例如制表符。使用 CSV 模块打开文件时,请保留 newline="",并选择与源数据相符的编码。如果行中含有带引号的字段或嵌入的换行符,应让 csv.reader 负责解析,而不要自行预处理各行。