我们将专门使用 Python 内置的 csv
模块来完成此任务。但首先,我们必须导入该模块,如下所示
import csv
我们已经介绍了如何使用 csv
模块读写 CSV 文件的基础知识。如果您对如何使用 csv
模块没有任何概念,请查看我们的教程 Python CSV:读写 CSV 文件
csv.writer() 的基本用法
让我们看一个使用 csv.
writer
()
的基本示例,以刷新您现有的知识。
示例 1:使用 csv.writer() 写入 CSV 文件
假设我们要编写一个包含以下条目的 CSV 文件
SN,Name,Contribution 1,Linus Torvalds,Linux Kernel 2,Tim Berners-Lee,World Wide Web 3,Guido van Rossum,Python Programming
下面是我们的做法。
import csv
with open('innovators.csv', 'w', newline='') as file:
writer = csv.writer(file)
writer.writerow(["SN", "Name", "Contribution"])
writer.writerow([1, "Linus Torvalds", "Linux Kernel"])
writer.writerow([2, "Tim Berners-Lee", "World Wide Web"])
writer.writerow([3, "Guido van Rossum", "Python Programming"])
当我们运行上述程序时,会在当前工作目录中创建一个包含给定条目的 innovators.csv 文件。
在这里,我们使用 open()
函数以写入模式打开了 innovators.csv 文件。
要了解更多关于在 Python 中打开文件的信息,请访问:Python 文件输入/输出
接下来,使用 csv.writer()
函数创建一个 writer
对象。然后使用 writer.writerow()
函数将单行写入 CSV 文件。
示例 2:使用 writerows() 写入多行
如果我们需要将二维列表的内容写入 CSV 文件,可以这样做。
import csv
row_list = [["SN", "Name", "Contribution"],
[1, "Linus Torvalds", "Linux Kernel"],
[2, "Tim Berners-Lee", "World Wide Web"],
[3, "Guido van Rossum", "Python Programming"]]
with open('protagonist.csv', 'w', newline='') as file:
writer = csv.writer(file)
writer.writerows(row_list)
程序的输出与示例 1 中相同。
在这里,我们的二维列表被传递给 writer.writerows()
函数,以将列表的内容写入 CSV 文件。
现在让我们看看如何以不同格式写入 CSV 文件。然后我们将学习如何自定义 csv.writer()
函数来写入它们。
带有自定义分隔符的 CSV 文件
默认情况下,逗号在 CSV 文件中用作分隔符。但是,一些 CSV 文件可能使用逗号以外的分隔符。一些常用的是 |
和 \t
。
假设我们想在示例 1 的 innovators.csv 文件中使用 |
作为分隔符。要写入此文件,我们可以向 csv.writer()
函数传递一个额外的 delimiter
参数。
让我们举个例子。
示例 3:写入使用管道符作为分隔符的 CSV 文件
import csv
data_list = [["SN", "Name", "Contribution"],
[1, "Linus Torvalds", "Linux Kernel"],
[2, "Tim Berners-Lee", "World Wide Web"],
[3, "Guido van Rossum", "Python Programming"]]
with open('innovators.csv', 'w', newline='') as file:
writer = csv.writer(file, delimiter='|')
writer.writerows(data_list)
输出
SN|Name|Contribution 1|Linus Torvalds|Linux Kernel 2|Tim Berners-Lee|World Wide Web 3|Guido van Rossum|Python Programming
正如我们所见,可选参数 delimiter = '|'
有助于指定 writer
对象,该 CSV 文件应使用 |
作为分隔符。
带引号的 CSV 文件
一些 CSV 文件在每个或某些条目周围有引号。
让我们以 quotes.csv 为例,它包含以下条目
"SN";"Name";"Quotes" 1;"Buddha";"What we think we become" 2;"Mark Twain";"Never regret anything that made you smile" 3;"Oscar Wilde";"Be yourself everyone else is already taken"
默认使用 csv.writer()
不会将这些引号添加到条目中。
为了添加它们,我们将不得不使用另一个名为 quoting
的可选参数。
让我们举一个例子,说明如何在非数值周围使用引号,并使用 ;
作为分隔符。
示例 4:写入带引号的 CSV 文件
import csv
row_list = [
["SN", "Name", "Quotes"],
[1, "Buddha", "What we think we become"],
[2, "Mark Twain", "Never regret anything that made you smile"],
[3, "Oscar Wilde", "Be yourself everyone else is already taken"]
]
with open('quotes.csv', 'w', newline='') as file:
writer = csv.writer(file, quoting=csv.QUOTE_NONNUMERIC, delimiter=';')
writer.writerows(row_list)
输出
"SN";"Name";"Quotes" 1;"Buddha";"What we think we become" 2;"Mark Twain";"Never regret anything that made you smile" 3;"Oscar Wilde";"Be yourself everyone else is already taken"
在这里,quotes.csv 文件在工作目录中创建,包含上述条目。
如您所见,我们将 csv.QUOTE_NONNUMERIC
传递给了 quoting
参数。它是 csv
模块定义的一个常量。
csv.QUOTE_NONNUMERIC
指定 writer
对象应在非数值条目周围添加引号。
您可以传递给 quoting
参数的还有 3 个其他预定义常量
csv.QUOTE_ALL
- 指定writer
对象在所有条目周围添加引号来写入 CSV 文件。csv.QUOTE_MINIMAL
- 指定writer
对象仅对包含特殊字符(delimiter、quotechar 或 lineterminator 中的任何字符)的字段加引号。csv.QUOTE_NONE
- 指定writer
对象不应对任何条目加引号。这是默认值。
带有自定义引号字符的 CSV 文件
我们还可以使用自定义引号字符写入 CSV 文件。为此,我们将不得不使用一个名为 quotechar
的可选参数。
让我们以在示例 4 中写入 quotes.csv 文件为例,但使用 *
作为引号字符。
示例 5:使用自定义引号字符写入 CSV 文件
import csv
row_list = [
["SN", "Name", "Quotes"],
[1, "Buddha", "What we think we become"],
[2, "Mark Twain", "Never regret anything that made you smile"],
[3, "Oscar Wilde", "Be yourself everyone else is already taken"]
]
with open('quotes.csv', 'w', newline='') as file:
writer = csv.writer(file, quoting=csv.QUOTE_NONNUMERIC,
delimiter=';', quotechar='*')
writer.writerows(row_list)
输出
*SN*;*Name*;*Quotes* 1;*Buddha*;*What we think we become* 2;*Mark Twain*;*Never regret anything that made you smile* 3;*Oscar Wilde*;*Be yourself everyone else is already taken*
在这里,我们可以看到 quotechar='*'
参数指示 writer
对象对所有非数值使用 *
作为引号。
CSV 模块中的方言 (Dialects)
注意在示例 5 中,我们向 csv.writer()
函数传递了多个参数(quoting
、delimiter
和 quotechar
)。
在处理一两个文件时,这种做法是可以接受的。但是一旦我们开始处理具有相似格式的多个 CSV 文件,它会使代码变得更加冗余和不美观。
作为对此的解决方案,csv
模块提供了 dialect
作为一个可选参数。
方言有助于将许多特定的格式化模式(如 delimiter
、skipinitialspace
、quoting
、escapechar
)组合到一个方言名称中。
然后它可以作为参数传递给多个 writer
或 reader
实例。
示例 6:使用方言写入 CSV 文件
假设我们要写入一个包含以下内容的 CSV 文件 (office.csv)
"ID"|"Name"|"Email" "A878"|"Alfonso K. Hamby"|"[email protected]" "F854"|"Susanne Briard"|"[email protected]" "E833"|"Katja Mauer"|"[email protected]"
该 CSV 文件在每个条目周围都有引号,并使用 |
作为分隔符。
与其传递两个单独的格式化模式,不如看看如何使用方言来写入此文件。
import csv
row_list = [
["ID", "Name", "Email"],
["A878", "Alfonso K. Hamby", "[email protected]"],
["F854", "Susanne Briard", "[email protected]"],
["E833", "Katja Mauer", "[email protected]"]
]
csv.register_dialect('myDialect',
delimiter='|',
quoting=csv.QUOTE_ALL)
with open('office.csv', 'w', newline='') as file:
writer = csv.writer(file, dialect='myDialect')
writer.writerows(row_list)
输出
"ID"|"Name"|"Email" "A878"|"Alfonso K. Hamby"|"[email protected]" "F854"|"Susanne Briard"|"[email protected]" "E833"|"Katja Mauer"|"[email protected]"
在这里,office.csv 在工作目录中创建,包含上述内容。
从这个例子中,我们可以看到 csv.register_dialect()
函数用于定义自定义方言。其语法是
csv.register_dialect(name[, dialect[, **fmtparams]])
自定义方言需要一个字符串形式的名称。其他规范可以通过传递 Dialect
类的子类,或像示例中那样通过单独的格式化模式来完成。
在创建 writer
对象时,我们传递 dialect='myDialect'
来指定 writer 实例必须使用该特定方言。
使用 dialect
的优点是它使程序更具模块化。请注意,我们可以重用 myDialect 来写入其他 CSV 文件,而无需重新指定 CSV 格式。
使用 csv.DictWriter() 写入 CSV 文件
csv.DictWriter()
类的对象可用于从 Python 字典写入 CSV 文件。
csv.DictWriter()
类的最小语法是
csv.DictWriter(file, fieldnames)
这里,
file
- 我们要写入的 CSV 文件fieldnames
- 一个list
对象,应包含列标题,指定数据在 CSV 文件中写入的顺序
示例 7:Python csv.DictWriter()
import csv
with open('players.csv', 'w', newline='') as file:
fieldnames = ['player_name', 'fide_rating']
writer = csv.DictWriter(file, fieldnames=fieldnames)
writer.writeheader()
writer.writerow({'player_name': 'Magnus Carlsen', 'fide_rating': 2870})
writer.writerow({'player_name': 'Fabiano Caruana', 'fide_rating': 2822})
writer.writerow({'player_name': 'Ding Liren', 'fide_rating': 2801})
输出
该程序创建一个包含以下条目的 players.csv 文件
player_name,fide_rating Magnus Carlsen,2870 Fabiano Caruana,2822 Ding Liren,2801
csv.DictWriter()
类的完整语法是
csv.DictWriter(f, fieldnames, restval='', extrasaction='raise', dialect='excel', *args, **kwds)
要了解更多详细信息,请访问:Python csv.DictWriter() 类
带 lineterminator 的 CSV 文件
lineterminator
是一个用于终止由 writer
对象产生的行的字符串。默认值为 \r\n
。您可以通过传递任何字符串作为 lineterminator
参数来更改其值。
然而,reader
对象只识别 \n
或 \r
作为 lineterminator
值。因此,非常不鼓励使用其他字符作为行终止符。
CSV 模块中的 doublequote 和 escapechar
为了分隔条目中的分隔符字符,csv
模块默认使用引号来引用条目。
因此,如果您有一个条目:He is a strong, healthy man,它将被写为:"He is a strong, healthy man"。
同样,csv
模块默认使用双引号来转义条目中存在的引号字符。
如果您有一个条目:Go to "programiz.com",它将被写为:"Go to ""programiz.com"""。
在这里,我们可以看到每个 "
后面都跟着一个 "
来转义前一个。
doublequote
它处理条目本身中存在的 quotechar
是如何被引用的。当为 True
时,引号字符会加倍;当为 False
时,escapechar
将用作 quotechar
的前缀。其默认值为 True
。
escapechar
如果 quoting 设置为 csv.QUOTE_NONE
,escapechar
参数是用于转义分隔符的字符串;如果 doublequote 为 False
,则用于转义 quotechar。其默认值为 None。
示例 8:在 csv writer 中使用 escapechar
import csv
row_list = [
['Book', 'Quote'],
['Lord of the Rings',
'"All we have to decide is what to do with the time that is given us."'],
['Harry Potter', '"It matters not what someone is born, but what they grow to be."']
]
with open('book.csv', 'w', newline='') as file:
writer = csv.writer(file, escapechar='/', quoting=csv.QUOTE_NONE)
writer.writerows(row_list)
输出
Book,Quote Lord of the Rings,/"All we have to decide is what to do with the time that is given us./" Harry Potter,/"It matters not what someone is born/, but what they grow to be./"
在这里,我们可以看到 /
是所有 "
和 ,
的前缀,因为我们指定了 quoting=csv.QUOTE_NONE
。
如果未定义,那么输出将是
Book,Quote Lord of the Rings,"""All we have to decide is what to do with the time that is given us.""" Harry Potter,"""It matters not what someone is born, but what they grow to be."""
由于我们允许引用,带有特殊字符(本例中为 "
)的条目被双引号引用。带有 delimiter
的条目也包含在引号字符内(起始和结束引号字符)。
剩余的引号字符用于转义字符串中实际存在的 "
,这样它们就不会被解释为 quotechar。
注意: csv 模块也可用于其他文件扩展名(如:.txt),只要其内容结构正确即可。
推荐阅读:在 Python 中读取 CSV 文件