csv 模块专门用于读取和写入 csv 文件内容
以下主要讲在 python2 中的使用,在python3中有不同的地方,我会单独指出来
一般的excel表格可以保存为csv格式,然后就可以使用 csv 模块去处理了
读取文件
读取文件通过 csv.reader() 方法
需要注意,在python2中,打开和写 csv 文件,使用 rb 和 wb
但在python3中,打开和写 csv 文件,使用 r 和 w
而且 python2 和 python3 在csv文件中遇到中文时的情况也不一样,具体见后面有关中文问题的介绍
import csv f = open("tmp.csv", "rb")
# 这里获得的 csvreader 变量实际上是一个迭代器,也就是不能直接打印,需要通过for循环或者next()方法读取,且只能读取一次
csvreader = csv.reader(f)
for row in csvreader:
# 这里的 row 为一个列表,每个字段为这个列表的一个元素,注意,每个字段都是字符串类型
# 为了保证每个字段的值前后没有空字符,可以使用如下方法将其处理以后获得新的列表
new_row = []
for i in row:
new_row.append(i.strip())
写文件
写文件通过csv.writer() 方法,
如果要一次写入一行,可以使用 writerow() 方法;如果要一次写多行,可以使用 writerows()
如下例:
f = open("tmp.csv", 'wb')
# 虽然读取出来都是字符串,但是写入时,可以是其他类,所以这里的3可以是数值,读取该文件时还是会都变成字符串
a = [["a",""],["b",""],["c",3]]
csvwriter = csv.writer(f) for i in a:
# 一次写入一行
csvwriter.writerow(i) # 一次写入多行
csvwriter.writerows([["d", 4], ["e", 5]])
f.close()
定义格式
定义格式的方法 register_dialect()
有很多格式可以定义,用的最多的是delimiter ,分隔符,默认是逗号
可以自定义其他格式:
csv.register_dialect("mydialect", delimiter="|")
定义一个格式,命名为mydialect,分隔符设定为 "|"
应用自定义格式的方式如下:
# 读文件时应用,读取文件时,按 "|" 分隔
f = open("tmp1.csv","rb")
lines = csv.reader(f, "mydialect") # 写文件时应用,写文件时,按 "|" 分隔
f = open("tmp1.csv","wb")
csvwriter = csv.writer(f, "mydialect")
中文问题
无论是python2,还是python3,无论是读还是写,都会遇到中文的问题
在python2中
读取文件时,如果原文件不是 utf-8 的编码格式(事实上,使用excel创建的csv文件,编码格式一般为gbk),则输出来的中文类似这种格式 '\xb2\xe2\xca\xd4',可以对该字符串使用decode("gbk")解码即可获得中文信息
写文件时,如果内容有中文,代码不会出问题,但是写出来的文件是utf-8的编码格式,使用vim和cat一般不会出问题,但是使用excel打开时,中文会显示乱码
但是写出的该 csv 文件,使用 csv 模块打开时就可以正常显示,为utf-8的编码格式
如果希望写出的带中文的 csv 文件可以被 excel 正常读取,可以使用codecs模块
import csv
import codecs f = codecs.open("tmp1.csv", "w", "utf_8_sig")
csvw = csv.writer(f)
csvw.writerows([["中国","中文"],["abc","中文"]])
7 f.close()
这种方法写的csv文件,在excel中也能正常显示中文,而且文件编码为utf-8
但是该csv文件使用csv模块打开时,会在第一个字段前加上 "\ufeff" 标记,在做字符串对比的时候需要注意这一点
>>> f = open("tmp1.csv", "r")
>>> csvr = csv.reader(f)
>>> next(csvr)
['\ufeff中国', '中文']
>>> next(csvr)
['abc', '中文']
在python3中,
读取非 utf-8 编码格式带中文的csv文件时,则直接报错
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xb2 in position 0: invalid start byte
但python3中有个很好的方式来解决这个问题
python3中,open函数有一个encoding参数,可以指定文件的编码格式,注意,这是python2中没有的
所以,在读取 gbk 编码格式的 csv 文件时,可以使用如下方法
>>> f = open("tmp2.csv","r", encoding="gbk")
>>> csvr = csv.reader(f)
>>> a = next(csvr)
>>> a[0]
'中文1'
>>> a[0] == '中文1'
True
注意,这里获得的中文是不是 gbk 编码,而是 unicode 编码,可以直接和 unicode 编码的中文进行比较
写带中文的csv文件时,也可以使用这种方式打开
>>> f = open("tmp3.csv", "w", encoding="gbk")
>>> csvw = csv.writer(f)
>>> csvw.writer([["中文1", "中文2"],["a","中文3"]])
>>> f.close()
这里创建的tmp3.csv文件是 gbk 编码格式,可以使用excel正常查看,但可能使用vim和cat查看时是乱码
vim可以更改vimrc中的fileencodings的值,来正常查看gbk格式的中文,具体方法这里就不介绍了
事实上,如果写文件时如果open函数不添加encoding参数,上面介绍的 python2 中的写方法同样适用于 python3