本文要点
假设练习目录里准备导出两条记录,每条是一个字典
确定列名后,导出动作分三步:建writer对象、写表头、逐条写数据
如果某条字典没有fieldnames里的某个键,DictWriter不会报错,而是用restval参数指定的值补上

本文目录
fieldnames是必填项,它决定列的先后顺序
先给结论:用DictWriter导出CSV,fieldnames必须自己写,而且它写什么顺序,输出文件里的列就是什么顺序。
这和读方向的DictReader不一样。DictReader的fieldnames是可选的,省略时会拿文件第一行当列名。DictWriter没有这个默认值:fieldnames是一个键的序列,用来确定传给writerow的字典里的值按什么次序写入文件。你不传它,对象就建不起来。
所以“按固定列名导出”这件事,第一步不是准备数据,而是先把想要的列名按顺序列出来。列名一旦定下,后面每条字典数据都按这个顺序落位,字典本身在内存里的排列顺序不影响输出。
本文只处理一个自建场景:两条字典数据,写成一个新的CSV文件。不涉及读取已有CSV、方言注册或引号参数。所有文件名和内容都是练习用的自建示例,不是对真实数据的记录。动手前请把练习文件放在单独的目录里,不要拿重要数据直接试。
自建两条字典数据:先写清楚输入长什么样
假设练习目录里准备导出两条记录,每条是一个字典。下面这段只是把数据写进脚本,不读取任何外部文件:
import csv
rows = [
{"name": "示例甲", "city": "示例城", "note": "第一条"},
{"name": "示例乙", "city": "示例镇", "note": "第二条"},
]这两条字典的键完全一样,是最好处理的情况。接下来要决定输出文件里出现哪些列、按什么顺序。比如你希望列顺序是 name、city、note,就把这三项按这个顺序写进fieldnames。
这里要分清两件事:字典里有哪些键,和CSV里要哪些列,是两回事。fieldnames是你对输出列的选择和排序,不是对字典键的自动照抄。你可以只导出其中一部分列,也可以调整它们的先后。
写出新文件:writeheader加writerow的完整顺序
确定列名后,导出动作分三步:建writer对象、写表头、逐条写数据。下面是最小可用写法,输出到练习目录下的新文件:
import csv
rows = [
{"name": "示例甲", "city": "示例城", "note": "第一条"},
{"name": "示例乙", "city": "示例镇", "note": "第二条"},
]
fieldnames = ["name", "city", "note"]
with open("exercise/out.csv", "w", newline="", encoding="utf-8") as f:
writer = csv.DictWriter(f, fieldnames=fieldnames)
writer.writeheader()
writer.writerows(rows)几个要点。第一,打开文件时用newline="",这是csv模块对文件对象的建议写法,避免换行被重复处理。第二,writeheader()按fieldnames的顺序写表头,不用你手写表头行。第三,writerows接收一个可迭代的行集合,也可以改用循环逐条writerow。
输出文件的第一行会是name,city,note,下面两行按同样顺序排。这是自建示例的预期结果,不是对某个真实文件的核对记录。
字典缺了某个键:restval决定补什么
如果某条字典没有fieldnames里的某个键,DictWriter不会报错,而是用restval参数指定的值补上。restval的默认值是空字符串。
举例:fieldnames仍是name、city、note,但第二条数据只有name和city,没有note。默认情况下,note那一列会写成空。如果你希望缺字段显示成别的占位内容,可以在建对象时传入restval:
writer = csv.DictWriter(f, fieldnames=fieldnames, restval="未提供")这样缺note的那一行,note列就会写成“未提供”。
要提醒的是,restval只处理“字典里没有这个键”的情况。它不会替你把空字符串、None这类已有值改写成别的。区分点在于:键不存在,走restval;键存在但值是空,就按原值写。
字典多了fieldnames以外的键:默认报错,可改为忽略
反过来的情况更需要注意。如果某条字典含有fieldnames里没有的键,DictWriter默认会抛ValueError,也就是extrasaction的默认值'raise'在起作用。
这意味着:你只导出name、city、note三列,但某条数据里还带着一个extra键,脚本会直接中断,而不是悄悄丢掉这一列。这个默认行为的好处是,多出来的字段不会被无声吞掉,你能立刻发现数据和列名对不上。
如果你确认多余的键不需要导出,可以在建对象时改成忽略:
writer = csv.DictWriter(f, fieldnames=fieldnames, extrasaction="ignore")改成ignore后,fieldnames之外的键会被跳过,文件里只出现你指定的列。选择raise还是ignore,取决于你想不想被提醒数据里有计划外的字段。
导出后怎么检查列顺序和字段处理对不对
文件写完后,别只看脚本有没有报错,回到输出文件本身核对三件事。
第一,看表头顺序。第一行是不是按你写的fieldnames排列,而不是按字典键的排列。第二,看缺字段的行。缺键的那一列,是不是按restval的设定显示,默认应为空。第三,看有没有多出来的列。如果用了默认的raise,多键会直接报错,文件可能没写完整;如果用了ignore,确认多出来的键确实没有出现在任何一列里。
一个简单的核对方法:把fieldnames抄在纸上,逐列对照文件表头,顺序和名称都要一致。这是编辑建议的检查方式,不是对某个文件的实测记录。
如果表头顺序和你预期不符,先回去检查fieldnames的书写顺序,而不是去改字典。列顺序由fieldnames决定,这是排查的起点。
适用限制与参考资料
本文只覆盖一个最小场景:两条自建字典数据,用DictWriter导出到新文件,重点在fieldnames决定列顺序,以及缺字段用restval、多余字段用extrasaction处理。
不涉及的内容包括:读取已有CSV、DictReader的用法、方言与引号参数、编码转换、大文件分批写入。这些不在本次范围内。
另外,fieldnames如果传入的是迭代器,会被转成列表,这一点在参考资料中有说明。本文示例统一用列表,避免这层转换带来的困惑。
所有操作只针对自建练习文件,不修改系统设置,也不删除文件。开始前建议把练习目录单独建好,输出文件用新名字,不要覆盖你已有的数据。
事实依据来自Python标准库csv模块文档中关于DictWriter的说明。文档没有给出的数值、性能结论或平台差异,本文不补充。
观看知识要点视频 18 秒
18秒无旁白要点导览,文字来自已审核正文;完整步骤、条件及参考资料见下方。
参考资料
以下原始资料提供本文依据;请结合日期、适用条件和产品说明查阅。
请结合原始资料的适用条件阅读。
返回表格与数据 →