csv 模塊專門用於讀取和寫入 csv 文件內容
以下主要講在 python2 中的使用,在python3中有不同的地方,我會單獨指出來
一般的excel表格可以保存為csv格式,然后就可以使用 csv 模塊去處理了
讀取文件
讀取文件通過 csv.reader() 方法
需要注意,在python2中,打開和寫 csv 文件,使用 rb 和 wb
但在python3中,打開和寫 csv 文件,使用 r 和 w
而且 python2 和 python3 在csv文件中遇到中文時的情況也不一樣,具體見后面有關中文問題的介紹
1 import csv 2 3 f = open("tmp.csv", "rb") 4 # 這里獲得的 csvreader 變量實際上是一個迭代器,也就是不能直接打印,需要通過for循環或者next()方法讀取,且只能讀取一次 5 csvreader = csv.reader(f) 6 for row in csvreader: 7 # 這里的 row 為一個列表,每個字段為這個列表的一個元素,注意,每個字段都是字符串類型 8 # 為了保證每個字段的值前后沒有空字符,可以使用如下方法將其處理以后獲得新的列表 9 new_row = [] 10 for i in row: 11 new_row.append(i.strip())
寫文件
寫文件通過csv.writer() 方法,
如果要一次寫入一行,可以使用 writerow() 方法;如果要一次寫多行,可以使用 writerows()
如下例:
1 f = open("tmp.csv", 'wb') 2 # 雖然讀取出來都是字符串,但是寫入時,可以是其他類,所以這里的3可以是數值,讀取該文件時還是會都變成字符串 3 a = [["a","1"],["b","2"],["c",3]] 4 csvwriter = csv.writer(f) 5 6 for i in a: 7 # 一次寫入一行 8 csvwriter.writerow(i) 9 10 # 一次寫入多行 11 csvwriter.writerows([["d", 4], ["e", 5]]) 12 f.close()
定義格式
定義格式的方法 register_dialect()
有很多格式可以定義,用的最多的是delimiter ,分隔符,默認是逗號
可以自定義其他格式:
1 csv.register_dialect("mydialect", delimiter="|")
定義一個格式,命名為mydialect,分隔符設定為 "|"
應用自定義格式的方式如下:
1 # 讀文件時應用,讀取文件時,按 "|" 分隔 2 f = open("tmp1.csv","rb") 3 lines = csv.reader(f, "mydialect") 4 5 # 寫文件時應用,寫文件時,按 "|" 分隔 6 f = open("tmp1.csv","wb") 7 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模塊
1 import csv 2 import codecs 3 4 f = codecs.open("tmp1.csv", "w", "utf_8_sig") 5 csvw = csv.writer(f) 6 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
