在 Python 中写入 CSV 文件

我们将专门使用 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

假设我们想在示例 1innovators.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 对象仅对包含特殊字符(delimiterquotecharlineterminator 中的任何字符)的字段加引号。
  • 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() 函数传递了多个参数(quotingdelimiterquotechar)。

在处理一两个文件时,这种做法是可以接受的。但是一旦我们开始处理具有相似格式的多个 CSV 文件,它会使代码变得更加冗余和不美观。

作为对此的解决方案,csv 模块提供了 dialect 作为一个可选参数。


方言有助于将许多特定的格式化模式(如 delimiterskipinitialspacequotingescapechar)组合到一个方言名称中。

然后它可以作为参数传递给多个 writerreader 实例。


示例 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_NONEescapechar 参数是用于转义分隔符的字符串;如果 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 文件

你觉得这篇文章有帮助吗?

我们的高级学习平台,凭借十多年的经验和数千条反馈创建。

以前所未有的方式学习和提高您的编程技能。

试用 Programiz PRO
  • 交互式课程
  • 证书
  • AI 帮助
  • 2000+ 挑战