雖然純文字檔 .txt
是個非常常見的格式,但是他並不適合用來存放結構化的資料。結構化的資料是什麼呢?例如:
姓名:王大明
科目:數學
分數:94.87 分
在 Python 裡面,可能會用字典來呈現:
data = {
"name": "王大明",
"subject": "math",
"score": 94.87,
}
如果用純文字來存放這類資料,在讀取時解析相當不容易,通常我們會使用 JSON 格式來進行資料存放,可以使用內建的 json
套件來操作:
import json
with open("data.json", "w", encoding="UTF-8") as fp:
json.dump(data, fp)
將檔案打開來看,會發現內容長的像這樣:
{"name": "\u738b\u5927\u660e", "subject": "math", "score": 94.87}
科目與分數的部份看起來相當正常,但是名字是發生了什麼事情 🤔 這是 json
套件預設會將所有內容以英數字或半形符號(統稱 ASCII 字元)輸出。一般中日韓語系的使用者並不喜歡這種設定,可以在 json.dump()
裡面加上 ensure_ascii=False
的參數,來避免中日韓文字被轉換成 ASCII 字元:
with open("data.json", "w", encoding="UTF-8") as fp:
json.dump(data, fp, ensure_ascii=False)
JSON 除了可以輸出字典以外,也可以輸出列表,例如:
data = [
{"name": "王大明", "subject": "math", "score": 94.87},
{"name": "鄭美麗", "subject": "english", "score": 98.76},
]
with open("data.json", "w", encoding="UTF-8") as fp:
json.dump(data, fp, ensure_ascii=False)
打開 data.json
會發現內容長的像這樣:
[{"name": "王大明", "subject": "math", "score": 94.87}, {"name": "鄭美麗", "subject": "english", "score": 98.76}, {"name": "葉大雄", "subject": "chinese", "score": 0}]
雖然輸出的內容是正確的,但是全部都擠在同一行,這樣太不適合閱讀了!可以加上 indent
參數,讓套件幫我們做點排版:
with open("data.json", "w", encoding="UTF-8") as fp:
json.dump(data, fp, ensure_ascii=False, indent=4)
這樣檔案內容就會根據階層進行縮排囉!
[
{
"name": "王大明",
"subject": "math",
"score": 94.87
},
{
"name": "鄭美麗",
"subject": "english",
"score": 98.76
},
{
"name": "葉大雄",
"subject": "chinese",
"score": 0
}
]
這樣的 JSON 操作在 Python 裡面相當頻繁,我通常會寫成函式方便到處使用:
import json
def load_json(path):
with open(path, "r", encoding="UTF-8") as fp:
return json.load(fp)
def dump_json(obj, path):
with open(path, "w", encoding="UTF-8") as fp:
json.dump(obj, fp, ensure_ascii=False, indent=4)
熟悉 JSON 操作對於資料科學的研究相當有幫助!