返回介绍

14.1 csv 模块

发布于 2024-01-22 21:44:06 字数 5525 浏览 0 评论 0 收藏 0

CSV文件中的每行代表电子表格中的一行,逗号分割了该行中的单元格。例如,来自http://nostarch.com/automatestuff/的电子表格example.xlsx,在一个CSV文件中,看起来像这样:

4/5/2015 13:34,Apples,73
4/5/2015 3:41,Cherries,85
4/6/2015 12:46,Pears,14
4/8/2015 8:59,Oranges,52
4/10/2015 2:07,Apples,152
4/10/2015 18:10,Bananas,23
4/10/2015 2:40,Strawberries,98

我将使用这个文件作为本章的交互式环境的例子。可以从http://nostarch.com/ automatestuff/下载example.csv,或在文本编辑器中输入文本,并保存为example.csv。

CSV文件是简单的,缺少Excel电子表格的许多功能。例如,CSV文件中:

· 值没有类型,所有东西都是字符串;

· 没有字体大小或颜色的设置;

· 没有多个工作表;

· 不能指定单元格的宽度和高度;

· 不能合并单元格;

· 不能嵌入图像或图表。

CSV的文件的优势是简单。CSV文件被许多种类的程序广泛地支持,可以在文本编辑器中查看(包括IDLE的文件编辑器),它是表示电子表格数据的直接方式。CSV格式和它声称的完全一致:它就是一个文本文件,具有逗号分隔的值。

因为CSV文件就是文本文件,所以你可能会尝试将它们读入一个字符串,然后用第8章中学到的技术处理这个字符串。例如,因为CSV文件中的每个单元格有逗号分割,也许你可以只是对每行文本调用split()方法,来取得这些值。但并非CSV文件中的每个逗号,都表示两个单元格之间的分界。CSV文件也有自己的转义字符,允许逗号和其他字符作为值的一部分。split()方法不能处理这些转义字符。因为这些潜在的缺陷,所以总是应该使用csv模块来读写CSV文件。

14.1.1 Reader对象

要用csv模块从CSV文件中读取数据,需要创建一个Reader对象。Reader对象让你迭代遍历CSV文件中的每一行。在交互式环境中输入以下代码,同时将example.csv放在当前工作目录中:

❶ >>> import csv
❷ >>> exampleFile = open('example.csv')
❸ >>> exampleReader = csv.reader(exampleFile)
❹ >>> exampleData = list(exampleReader)
❺ >>> exampleData
 [['4/5/2015 13:34', 'Apples', '73'], ['4/5/2015 3:41', 'Cherries', '85'],
 ['4/6/2015 12:46', 'Pears', '14'], ['4/8/2015 8:59', 'Oranges', '52'],
 ['4/10/2015 2:07', 'Apples', '152'], ['4/10/2015 18:10', 'Bananas', '23'],
 ['4/10/2015 2:40', 'Strawberries', '98']]

csv模块是Python自带的,所以不需要安装就可以导入它❶。

要用csv模块读取CSV文件,首先用open()函数打开它❷,就像打开任何其他文本文件一样。但是,不用在open()返回的File对象上调用read()或readlines()方法,而是将它传递给csv.reader()函数❸。这将返回一个Reader对象,供你使用。请注意,不能直接将文件名字符串传递给csv.reader()函数。

要访问Reader对象中的值,最直接的方法,就是将它转换成一个普通Python列表,即将它传递给list()❹。在这个Reader对象上应用list()函数,将返回一个列表的列表。可以将它保存在变量exampleData中。在交互式环境中输入exampleData,将显示列表的列表❺。

既然已经将CSV文件表示为列表的列表,就可以用表达式exampleData [row][col]来访问特定行和列的值。其中,row是exampleData中一个列表的下标,col是该列表中你想访问的项的下标。在交互式环境中输入以下代码:

>>> exampleData[0][0]
'4/5/2015 13:34'
>>> exampleData[0][1]
'Apples'
>>> exampleData[0][2]
'73'
>>> exampleData[1][1]
'Cherries'
>>> exampleData[6][1]
'Strawberries'

exampleData[0][0]进入第一个列表,并给出第一个字符串。exampleData[0][2]进入第一个列表,并给出第三个字符串,以此类推。

14.1.2 在for循环中,从Reader对象读取数据

对于大型的CSV文件,你需要在一个for循环中使用Reader对象。这样避免将整个文件一次性装入内存。例如,在交互式环境中输入以下代码:

>>> import csv
>>> exampleFile = open('example.csv')
>>> exampleReader = csv.reader(exampleFile)
>>> for row in exampleReader:
        print('Row #' + str(exampleReader.line_num) + ' ' + str(row))

Row #1 ['4/5/2015 13:34', 'Apples', '73']
Row #2 ['4/5/2015 3:41', 'Cherries', '85']
Row #3 ['4/6/2015 12:46', 'Pears', '14']
Row #4 ['4/8/2015 8:59', 'Oranges', '52']
Row #5 ['4/10/2015 2:07', 'Apples', '152']
Row #6 ['4/10/2015 18:10', 'Bananas', '23']
Row #7 ['4/10/2015 2:40', 'Strawberries', '98']

在导入csv模块,并从CSV文件得到Reader对象之后,可以循环遍历Reader对象中的行。每一行是一个值的列表,每个值表示一个单元格。

print()函数将打印出当前行的编号以及该行的内容。要取得行号,就使用Reader对象的line_num变量,它包含了当前行的编号。

Reader对象只能循环遍历一次。要再次读取CSV文件,必须调用csv.reader,创建一个对象。

14.1.3 Writer对象

Writer 对象让你将数据写入 CSV 文件。要创建一个 Writer 对象,就使用csv.writer()函数。在交互式环境中输入以下代码。

 >>> import csv
❶ >>> outputFile = open('output.csv', 'w', newline='')
❷ >>> outputWriter = csv.writer(outputFile)
 >>> outputWriter.writerow(['spam', 'eggs', 'bacon', 'ham'])
 21
 >>> outputWriter.writerow(['Hello, world!', 'eggs', 'bacon', 'ham'])
 32
 >>> outputWriter.writerow([1, 2, 3.141592, 4])
 16
 >>> outputFile.close()

首先,调用open()并传入'w',以写模式打开一个文件❶。这将创建对象。然后将它传递给csv.writer()❷,创建一个Writer对象。

在Windows上,需要为open()函数的newline关键字参数传入一个空字符串。这样做的技术原因超出了本书的范围。如果忘记设置newline关键字参数,output.csv中的行距将有两倍,如图14-1所示。

图14-1 如果你在open()中忘记了newline=''关键字参数,CSV文件将有两倍行距

Writer对象的writerow()方法接受一个列表参数。列表中的每个词,放在输出的CSV文件中的一个单元格中。writerow()函数的返回值,是写入文件中这一行的字符数(包括换行字符)。

这段代码生成的文件像下面这样:

spam,eggs,bacon,ham
"Hello, world!",eggs,bacon,ham
1,2,3.141592,4

请注意,Writer对象自动转义了'Hello, world!'中的逗号,在CSV文件中使用了双引号。模块csv让你不必自己处理这些特殊情况。

14.1.4 delimiter和lineterminator关键字参数

假定你希望用制表符代替逗号来分隔单元格,并希望有两倍行距。可以在交互式环境中输入下面这样的代码:

 >>> import csv
 >>> csvFile = open('example.tsv', 'w', newline='')
❶ >>> csvWriter = csv.writer(csvFile, delimiter='\t', lineterminator='\n\n')
 >>> csvWriter.writerow(['apples', 'oranges', 'grapes'])
 24
 >>> csvWriter.writerow(['eggs', 'bacon', 'ham'])
 17
 >>> csvWriter.writerow(['spam', 'spam', 'spam', 'spam', 'spam', 'spam'])
 32
 >>> csvFile.close()

这改变了文件中的分隔符和行终止字符。分隔符是一行中单元格之间出现的字符。默认情况下,CSV文件的分隔符是逗号。行终止字符是出现在行末的字符。默认情况下,行终止字符是换行符。你可以利用csv.writer()的delimiter和lineterminator关键字参数,将这些字符改成不同的值。

传入delimeter='\t'和lineterminator='\n\n'❶,这将单元格之间的字符改变为制表符,将行之间的字符改变为两个换行符。然后我们调用writerow()三次,得到3行。

这产生了文件example.tsv,包含以下内容:

apples  oranges grapes

eggs    bacon    ham

spam    spam     spam     spam     spam     spam

既然单元格是由制表符分隔的,我们就使用文件扩展名.tsv,表示制表符分隔的值。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文