Python 通过其内置模块提供的便利真的很有价值,对于
csv
模块也是如此。
微信搜索关注《Python学研大本营》,加入读者群,分享更多精彩
您很有可能遇到或必须使用 CSV(逗号分隔值)文件。CSV 文件包含类似于电子表格的数据。它用 分隔符分隔 ,因此它不必总是逗号。但是,由于它是一个 逗号分隔值 文件,让我们看一个这样的示例:
# 📁 students.csv
first,last,house
Harry,Potter,Gryffindor
Hermione,Granger,Gryffindor
Luna,Lovegood,Ravenclaw
Draco,Malfoy,Slytherin
如上例所示,第一行 ( first,last,house
) 可用于标题作为列名。
Python方便地有一个内置的 csv
模块以有效的方式处理 CSV 文件。两个基本操作是读和写;使用 Python,我们可以使用列表(或更一般地,任何可迭代的)或字典来执行这些操作。
csv.reader()
要读取 CSV 文件,一种选择是使用 csv.reader()
方法。让我们看一个简单的例子 students.csv
文件:
import csv
with open('students.csv') as csvfile:
reader = csv.reader(csvfile)
for row in reader:
if row == ['first', 'last', 'house']:
continue
print(f'{row[0]} {row[1]} is in {row[2]}.')
# Harry Potter is in Gryffindor.
# Hermione Granger is in Gryffindor.
# Luna Lovegood is in Ravenclaw.
# Draco Malfoy is in Slytherin.
我们使用 context manager (https://docs.python.org/3/glossary.html#term-context-manager) 来打开我们的文件。(请注意,我们不需要指定 'r'
参数作为读取操作的模式,因为它是默认值;请参阅 官方文档 (https://docs.python.org/3/library/functions.html#open) 。) 当我们使用 csv.reader()
,它返回一个阅读器对象,我们将其存储在 reader
多变的。然后,用一个 for
循环,我们遍历每一行,这是一个列表——并且,因为我们的第一行实际上是标题,我们通过该迭代并继续。实际上, csv.DictReader()
对此有更好的可用性,我们稍后会看到。这里重要的一点是每一行都是一个 list
包含三个元素,我们通过索引访问它们( row[0]
, row[1]
, row[2]
)。这不是最优雅的实现,而是一个足够简单的例子来看看如何 csv.reader()
作品。
csv.writer()
假设我们想将 Ron Weasley 添加到我们的 CSV 文件中,因为我们希望我们的黄金三重奏在一起。让我们看看我们如何去做:
import csv
with open('students.csv', 'a') as csvfile:
writer = csv.writer(csvfile)
writer.writerow(['Ron', 'Weasley', 'Gryffindor'])
在这里,我们再次使用上下文管理器打开我们的 CSV 文件,这次使用 'a'
参数作为附加到它的模式。之后,我们使用 csv.writer()
,将我们的文件对象传递给它。它返回一个 writer 对象,我们将其存储在 writer
变量。然后,我们调用 writerow()
添加罗恩韦斯莱的方法。一个重要的事情是我们通过了一个 list
作为一个论点,虽然它不一定是 list
— 我们可以使用像元组这样的可迭代对象,但使用列表更为常见。
现在,我们的文件看起来像:
# 📁 students.csv
first,last,house
Harry,Potter,Gryffindor
Hermione,Granger,Gryffindor
Luna,Lovegood,Ravenclaw
Draco,Malfoy,Slytherin
Ron,Weasley,Gryffindor
csv.DictReader()
我们可以改进上一个示例以读取 CSV 文件。让我们使用 csv.DictReader()
这次:
import csv
with open('students.csv') as csvfile:
reader = csv.DictReader(csvfile)
for row in reader:
print(f'{row["first"]} {row["last"]} is in {row["house"]}.')
# Harry Potter is in Gryffindor.
# Hermione Granger is in Gryffindor.
# Luna Lovegood is in Ravenclaw.
# Draco Malfoy is in Slytherin.
# Ron Weasley is in Gryffindor.
像 csv.reader()
, csv.DictReader()
返回一个阅读器对象,但这一次,正如文档所说,它“将每一行中的信息映射到 dict
其键由可选的 fieldnames 参数给出。” 如果您已经意识到,我们没有指定 fieldnames
参数,所以第一行被用作默认字段名。我们可以通过查看 fieldnames我们的阅读器对象的属性:
import csv
with open('students.csv') as csvfile:
reader = csv.DictReader(csvfile)
print(reader.fieldnames) # ['first', 'last', 'house']
csv.DictReader()
绝对使代码比以前的方法更具可读性。让我们看看如何再次使用字典,这次是写入文件。
csv.DictWriter()
之前我们已将罗恩·韦斯莱添加到我们的 students.csv
, 让我们这次再加一个韦斯莱,金妮。让我们看看如何用csv.DictWriter()
来做。:
import csv
with open('students.csv', 'a') as csvfile:
writer = csv.DictWriter(csvfile, fieldnames=['first', 'last', 'house'])
writer.writerow({'first': 'Ginny', 'last': 'Weasley', 'house': 'Gryffindor'})
我们再次附加到我们的文件,就像我们做的那样 csv.writer()
. 我们创建一个 writer 对象 csv.DictWriter()
,当然将文件对象本身传递给它,然后将返回的写入器对象分配给变量 writer
. 注意这里我们传递了一个名为 fieldnames
同样,这是一个包含字段名的列表。它不是可选参数,因此我们每次使用时都必须提供它 csv.DictWriter()
. 我们使用 writerow()
再次调用方法,但这一次,我们向它传递了一个字典,其键是我们刚刚指定的字段名。现在我们的文件看起来像这样:
# 📁 students.csv
first,last,house
Harry,Potter,Gryffindor
Hermione,Granger,Gryffindor
Luna,Lovegood,Ravenclaw
Draco,Malfoy,Slytherin
Ron,Weasley,Gryffindor
Ginny,Weasley,Gryffindor
现在,如果在里面 writerow()
你传入一个不在字段名中的键怎么办?显然,我们将有一个 ValueError
,但让我们看一个例子。他们说房子不是家,但想象一下我们错误地将格兰芬多写成金妮的 home
,而不是她 house
正如我们在 fieldnames 。让我们来看看:
import csv
with open('students.csv', 'a') as csvfile:
writer = csv.DictWriter(csvfile, fieldnames=['first', 'last', 'house'])
writer.writerow({'first': 'Ginny', 'last': 'Weasley', 'home': 'Gryffindor'})
# ValueError: dict contains fields not in fieldnames: 'home'
这实际上来自可选 extrasaction
里面的参数 csv.DictWriter()
. 它的默认值为 'raise'
中找不到键时 字段名 ,它会引发一个 ValueError
. 但是,我们可以通过传递值来强制它忽略它 'ignore'
. 所以,如果我们这样做:
import csv
with open('students.csv', 'a') as csvfile:
writer = csv.DictWriter(csvfile, fieldnames=['first', 'last', 'house'], extrasaction='ignore')
writer.writerow({'first': 'Ginny', 'last': 'Weasley', 'home': 'Gryffindor'})
在这种情况下,我们将完全忽略密钥,导致我们的文件如下所示:
# 📁 students.csv
first,last,house
Harry,Potter,Gryffindor
Hermione,Granger,Gryffindor
Luna,Lovegood,Ravenclaw
Draco,Malfoy,Slytherin
Ron,Weasley,Gryffindor
Ginny,Weasley,
不过,这不是最明智的决定,最好在这种情况下出错,除非我们有理由不这样做。
我们也可以使用 writerows()
方法,通过写入多行。它需要一个可迭代的参数,所以假设我们在韦斯莱双胞胎的列表中有两个字典,我们可以同时添加它们:
import csv
with open('students.csv', 'a') as csvfile:
writer = csv.DictWriter(csvfile, fieldnames=['first', 'last', 'house'])
twins = [
{'first': 'Fred', 'last': 'Weasley', 'house': 'Gryffindor'},
{'first': 'George', 'last': 'Weasley', 'house': 'Gryffindor'}
]
writer.writerows(twins)
现在,我们的文件看起来像:
# 📁 students.csv
first,last,house
Harry,Potter,Gryffindor
Hermione,Granger,Gryffindor
Luna,Lovegood,Ravenclaw
Draco,Malfoy,Slytherin
Ron,Weasley,Gryffindor
Ginny,Weasley,Gryffindor
Fred,Weasley,Gryffindor
George,Weasley,Gryffindor
引用常量
尤其是在使用 writer 对象时,我们可能需要指定如何引用字段——例如,处理字段可能包含分隔符本身的情况。为此,我们可以使用可选的 quoting
方法的参数,以及 quotechar
参数指定使用哪个字符作为引号。
这 csv
模块有四个常量用于 quoting
:
csv.QUOTE_ALL
: 引用所有字段。csv.QUOTE_MINIMAL
: 引用有特殊字符的字段(例如分隔符本身)。csv.QUOTE_NONNUMERIC
: 引用所有非数字字段。csv.QUOTE_NONE
: 从不引用字段。如果分隔符出现在其中一个字段中,则 escapechar
使用字符。如果 escapechar
未提供,它将引发错误。
让我们看一个简单的例子 csv.QUOTE_ALL
使用 csv.DictWriter()
. 可以想象,它将引用所有字段:
import csv
with open('students.csv', 'a') as csvfile:
writer = csv.DictWriter(csvfile, fieldnames=['first', 'last', 'house'], quotechar='"', quoting=csv.QUOTE_ALL)
writer.writerow({'first': 'Cho', 'last': 'Chang', 'house': 'Ravenclaw'})
现在,Cho Chang 的字段全部用引号引起来:
# 📁 students.csv
first,last,house
Harry,Potter,Gryffindor
Hermione,Granger,Gryffindor
Luna,Lovegood,Ravenclaw
Draco,Malfoy,Slytherin
Ron,Weasley,Gryffindor
Ginny,Weasley,Gryffindor
Fred,Weasley,Gryffindor
George,Weasley,Gryffindor
"Cho","Chang","Ravenclaw"
结论
Python 通过其内置模块提供的便利真的很有价值,对于 csv
模块也是如此。这篇文章探讨了读写 CSV 文件的非常简单的操作,但总有很多东西需要探索,而第一站总是官方文档(https://docs.python.org/3/library/csv.html)。希望你现在明白了处理CSV文件的一些基本知识。
编码愉快。
参考文章:https://dev.to/rivea0/csv-operations-101-with-pythons-own-csv-module-39b5
推荐书单
《Python从入门到精通》
https://item.jd.com/13284890.html
《Python从入门到精通(第2版)》从初学者角度出发,通过通俗易懂的语言、丰富多彩的实例,详细介绍了使用Python进行程序开发应该掌握的各方面技术。全书共分23章,包括初识Python、Python语言基础、运算符与表达式、流程控制语句、列表和元组、字典和集合、字符串、Python中使用正则表达式、函数、面向对象程序设计、模块、异常处理及程序调试、文件及目录操作、操作数据库、GUI界面编程、Pygame游戏编程、网络爬虫开发、使用进程和线程、网络编程、Web编程、Flask框架、e起去旅行网站、AI图像识别工具等内容。所有知识都结合具体实例进行介绍,涉及的程序代码都给出了详细的注释,读者可轻松领会Python程序开发的精髓,快速提升开发技能。除此之外,该书还附配了243集高清教学微视频及PPT电子教案。
《Python从入门到精通(第2版)》可作为软件开发入门者的学习用书,也可作为高等院校相关专业的教学参考用书,还可供开发人员查阅、参考使用。
这本书有如下特色:
-
循序渐进,实战讲述
-
243集教学微课视频,39小时知识点精讲,可听可看,随时随地扫码学
-
趣味解读,易教易学
-
赠送Python实战训练背记手册
-
在线解答,高效学习
企业QQ、QQ群在线答疑,明日学院社区答疑。
每周清大文森学堂在线直播答疑。
精彩回顾
微信搜素关注《Python学研大本营》
访问【IT今日热榜】,发现每日技术热点