iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 16
0
Software Development

從零開始學Python系列 第 16

[Day 16] 從零開始學Python - 檔案讀寫:妳出現在我詩的每一頁(中)

  • 分享至 

  • xImage
  •  

註:本文同步刊載在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來處理就好!)
其結果應該如下:
https://ithelp.ithome.com.tw/upload/images/20200929/20119871M1oviuTJBG.jpg
接著我們嘗試將其讀回來,
這時候就要改成用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囉!
明天見~


上一篇
[Day 15] 從零開始學Python - 檔案讀寫:妳出現在我詩的每一頁(上)
下一篇
[Day 17] 從零開始學Python - 檔案讀寫:妳出現在我詩的每一頁(下)
系列文
從零開始學Python30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言