1. 程式人生 > >csv 模組的基本使用

csv 模組的基本使用

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() 如下例: <wiz_code_mirror>              
f = open("tmp.csv", 'wb')
# 雖然讀取出來都是字串,但是寫入時,可以是其他類,所以這裡的3可以是數值
a = [["a","1"],["b","2"],["c",3]]
csvwriter = csv.writer(f)
 
for i in a:
    # 一次寫入一行
    csvwriter.writerow(i)
 
# 一次寫入多行
csvwriter.writerows([["d", 4], ["e", 5]])
f.close()
   

定義格式

定義格式的方法 register_dialect() 有很多格式可以定義,用的最多的是delimiter ,分隔符,預設是逗號 可以自定義其他格式: <wiz_code_mirror>              
csv.register_dialect("mydialect", delimiter="|")
    定義一個格式,命名為mydialect,分隔符設定為 "|" 應用自定義格式的方式如下: <wiz_code_mirror>              
# 讀檔案時應用,讀取檔案時,按 "|" 分隔
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模組 <wiz_code_mirror>          
import csv
import codecs
 
f = codecs.open("tmp1.csv", "w", "utf_8_sig")
csvw = csv.writer(f)
csvw.writerows([["中國","中文"],["abc","中文"]])
   
f.close()
      這種方法寫的csv檔案,在excel中也能正常顯示中文,而且檔案編碼為utf-8 但是該csv檔案使用csv模組開啟時,會在第一個欄位前加上 "\ufeff" 標記,在做字串對比的時候需要注意這一點 <wiz_code_mirror>              
>>> f = open("tmp1.csv", "r")
>>> csvr = csv.reader(f)
>>> next(csvr)
['\ufeff中國', '中文']
>>> next(csvr)
['abc', '中文']
      在python3中, 讀取非 utf-8 編碼格式帶中文的csv檔案時,則直接報錯 <wiz_code_mirror>              
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xb2 in position 0: invalid start byte
    但python3中有個很好的方式來解決這個問題,python3中,open函式有一個encoding引數,可以指定檔案的編碼格式,注意,這是python2中沒有的 所以,在讀取 gbk 編碼格式的 csv 檔案時,可以使用如下方法 <wiz_code_mirror>              
>>> 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檔案時,也可以使用這種方式開啟 <wiz_code_mirror>              
>>> 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格式的中文,具體方法這裡就不介紹了   事實上,如果寫檔案時不新增encoding引數,python2 和 python3 在寫帶中文的csv檔案時是一樣的