Python JSON & JSONL

何謂JSON

JSON全名是(JavaScript Object Notation,JavaScript物件表示法),
是一種資料格式,
並支援多種程式語言

json的資料格式有2種:

  • 物件(object): 一般用大括號{}表示
  • 陣列(array): 一般用中括號[]表示

JSON物件

json的物件以(key-value)的方式儲存,很像是python裡的字典,
例如說{"Name": "Horse", "age": 10}是一個物件的例子

注意json物件的key值只能是文字,比如說{10: "age"}是錯誤的例子
另外注意json的字串是雙引號

JSON陣列

陣列由一系列的值組成,
裡面可以放數值(number)、字串(string)、布林值(bool)、陣列(list)、null值,
很像是python的列表

在python內運用json模組

要使用json模組,在程式內需寫一行引入json模組

import json

上述介紹了json的資料格式定義,
不過在python程式中,json的資料是以字串的方式呈現

dumps與loads函數

在模組json中,我們要記兩個函數dumps與loads:

  • dumps: 將python的資料轉換成json格式
  • loads: 將json格式的資料轉換成python的資料

以下會給出許多例子

dumps基礎範例

import json

L = [2, 5, 6, "AA", "BB"]
jsonData = json.dumps(L)
print(jsonData)
print(type(jsonData))

結果:
[2, 5, 6, "AA", "BB"]
<class 'str'>

可以看到jsonData的型別是字串

dumps的sort_keys參數

python內的字典是無序的資料,
若在dumps函數內加入參數sort_keys = True
可以將轉成json的格式的物件資料依key值排序

import json

L = {'Zebra':15, 'bob':20, 'dog': 10, 'Alice': 60, 'david': -3}
jsonData = json.dumps(L)
jsonData_sort = json.dumps(L, sort_keys = True)
print("未排序:", jsonData)
print("排序後:", jsonData_sort)

結果: (小寫字母在大寫字母後面)
未排序: {"Zebra": 15, "bob": 20, "dog": 10, "Alice": 60, "david": -3}
排序後: {"Alice": 60, "Zebra": 15, "bob": 20, "david": -3, "dog": 10}

dumps的indent參數

我們可以在dumps函數內加入參數indent=4
設定縮排四個字元,讓資料方便閱讀,範例:

import json

L = {'Zebra':15, 'bob':20, 'dog': 10, 'Alice': 60, 'david': -3}
jsonData_sort = json.dumps(L, sort_keys = True, indent=4)
print(jsonData_sort)

結果:

{
    "Alice": 60,
    "Zebra": 15,
    "bob": 20,
    "david": -3,
    "dog": 10
}

loads基礎範例

在python內建立json資料記得加上引號,
因為json在python內是以字串的方式呈現,
範例:

import json

jsonObj = '{"Zebra": 15, "bob": 20, "dog": 10, "Alice": 60, "david": -3}' 
D = json.loads(jsonObj)
print(D)
print(type(D))

結果:

{'Zebra': 15, 'bob': 20, 'dog': 10, 'Alice': 60, 'david': -3}
<class 'dict'>

而且因為json的字串是用雙引號,
在python內宣告json物件時必須用單引號包雙引號,
比如說改這樣寫"{'Zebra': 15, 'bob': 20, 'dog': 10, 'Alice': 60, 'david': -3}"就不行

如何用dump與load存/讀json檔案?

講完了基礎用法,自然要學如何存檔和讀檔啦
這邊要特別注意,用來存/讀檔的函數名稱是叫作dump與load,
函數名稱後面沒有加s,
剛剛在python內將python資料與以字串呈現的json格式轉換的函數名稱是叫作dumps與loads,
函數名稱後面有加s,
不仔細看很容易寫錯還找不到bug,
需要特別注意函數名稱有沒有打錯

在python中讀/寫檔的語法為with...open
存檔範例:

import json

L = {'Zebra':15, 'bob':20, 'dog': 10, 'Alice': 60, 'david': -3}
file = 'data.json'
with open(file, 'w') as obj:
    json.dump(L, obj)

執行完程式後,你可以在程式的同一個資料夾,
找到data.json檔案,用記事本開啟它看結果:

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

讀檔範例: (將剛剛存檔的data.json檔讀進python)

import json
file = 'data.json'
with open(file, 'r') as obj:
    data = json.load(obj)

print(data)
print(type(data))

結果:
{'Zebra': 15, 'bob': 20, 'dog': 10, 'Alice': 60, 'david': -3}
<class 'dict'>

注意將json檔讀檔進來後就是python的字典型態,
而非字串

JSONL(JSON Lines)

其文件格式及為每一行都是一個獨立JSON資料結構,該格式可以用來記多筆相同資料結構的JSON資料,例如:

{"role": "system", "content": "中央大學"}
{"role": "system", "content": "台灣大學"}
{"role": "system", "content": "成功大學"}
{"role": "system", "content": "中原大學"}
{"role": "system", "content": "健行科技大學"}
{"role": "system", "content": "台北海洋大學"}
{"role": "system", "content": "中山大學"}