註:本文同步刊載在Medium,若習慣Medium的話亦可去那邊看呦!
上一回我們簡單介紹了如何讀一般的文字檔案,
那如果格式比較特別呢?
通常狀況下,會需要特別格式的原因,
是因為它代表了一段「資料」,
也就是說,讀取不同格式的檔案,
基本上就是在透過大家約定好的格式方法,
將資料從檔案中按規則讀出來。
以Python來說,最常見被拿來儲存的格式有CSV, XML, YAML, JSON等,
接下來的兩篇文章中,讓我們來分別介紹CSV和JSON吧!
CSV
CSV是相當淺顯易懂的格式,
如果讀者有在用Excel時,存檔時就會看到有CSV的選項。
一般而言,一個CSV檔案中,
每一個row(列)的不同單位常以逗號分隔,
(也有用tab鍵的,相當於'\t')
而column(行)的計算則是以換行符號為準。
(Unix/Mac系統使用'\n',Windows系統則用'\r\n')
註:中國和台灣在指稱列跟行時是剛好相反的,容易搞混。
如果沒有特別需求的話,直接使用row/column來對應稱呼橫向/直向就好。
還記得我們之前的三個同學的成績嗎?
ming = Student('阿明', {'數學':55, '英文':70, '物理':55})
mei = Student('小美', {'數學':90, '英文':88, '物理':100})
howhow = Student('HowHow', {'數學':80, '英文':60, '物理':40})
如果今天我們要使用csv的方式將這個成績記錄起來,
我們可能會考慮寫成這樣:
姓名, 數學, 英文, 物理
阿明, 55, 70, 55
小美, 90, 88, 100
HowHow, 80, 60, 40
那麼,我們怎麼存放到csv中呢?
Python中有內建一個csv的模組,
我們可以用其writer的writerow()或writerows()來處理:
import csv
with open('student.csv', 'w', newline='') as f:
csvw = csv.writer(f, delimiter=' ') # delimiter預設是',',可以自己更改
csvw.writerow(['姓名', '數學', '英文', '物理']) # 一次寫一個row
students = [
['阿明', 55, 70, 55],
['小美', 90, 88, 100],
['HowHow', 80, 60, 40]
]
csvw.writerows(students) # 一次寫多個rows
(delimiter是指分隔符號)
特別留意,在使用csv來處理時,開啟檔案請務必設置參數, newline='',
以避免掉作業系統對於換行的處理不同的問題。
(全部交由csv writer來處理就好!)
其結果應該如下:
接著我們嘗試將其讀回來,
這時候就要改成用csv的reader,
reader的部分比較簡單,我們可以用for...in...的方式來按row取出:
import csv
with open('student.csv', 'r') as f:
csvr = csv.reader(f, delimiter=' ') #
student_from_file = [row for row in csvr]
print(student_from_file)
讀出來的結果如下。
C:\Users\Desolve>python fromzero.py
[['姓名', '數學', '英文', '物理'], ['阿明', '55', '70', '55'], ['小美', '90', '88', '100'], ['HowHow', '80', '60', '40']]
那麼,如果是要處理字典呢?
我們可以使用DictWriter/DictReader。
假定我們已經有一段關於三名學生的字典:
{'姓名':'阿明', '數學':55, '英文':70, '物理':55}
{'姓名':'小美', '數學':90, '英文':88, '物理':100}
{'姓名':'HowHow','數學':80, '英文':60, '物理':40}
我們可以用如下的方式來寫入:
import csv
with open('student_dic.csv', 'w', newline='') as f:
field = ['姓名', '數學', '英文', '物理'] # 第一個row做為欄位名稱
csvw = csv.DictWriter(f, delimiter=' ', fieldnames=field)
csvw.writeheader()
csvw.writerow({'姓名':'阿明', '數學':55, '英文':70, '物理':55})
csvw.writerow({'姓名':'小美', '數學':90, '英文':88, '物理':100})
csvw.writerow({'姓名':'HowHow','數學':80, '英文':60, '物理':40})
with open('student_dic.csv', 'r') as f:
# DictReader將第一個row當做欄位名稱,所以就省略了
csvr = csv.DictReader(f, delimiter=' ')
student = [row for row in csvr]
print(student)
讀出來應該如下:
C:\Users\Desolve>python fromzero.py
[{'姓名': '阿明', '數學': '55', '英文': '70', '物理': '55'}, {'姓名': '小美', '數學': '90', '英文': '88', '物理': '100'}, {'姓名': 'HowHow', '數學': '80', '英文': '60', '物理': '40'}]
上面敘述的所有範例,在讀寫未知的檔案時,
我們都無法保證是否csv能夠正常運作,
所以最好還是用一下try...except的方法,
對於csv模組傳出的錯誤,
可以使用try...except csv.Error as e:來接取。
還吃得消嗎?加油!
那我們下一篇再來談談JSON囉!
明天見~