# 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模組
```python
import json
```
上述介紹了json的資料格式定義,
不過在python程式中,json的資料是以**字串**的方式呈現
## dumps與loads函數
在模組json中,我們要記兩個函數dumps與loads:
- dumps: 將python的資料轉換成json格式
- loads: 將json格式的資料轉換成python的資料
以下會給出許多例子
### dumps基礎範例
```python
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值排序
```python
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`,
設定縮排四個字元,讓資料方便閱讀,範例:
```python
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內是以**字串**的方式呈現,
範例:
```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`
存檔範例:
```python
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`檔案,用記事本開啟它看結果:
![https://ithelp.ithome.com.tw/upload/images/20200816/201171144Ze5qrkpC7.png](https://ithelp.ithome.com.tw/upload/images/20200816/201171144Ze5qrkpC7.png)
讀檔範例: (將剛剛存檔的data.json檔讀進python)
```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資料,例如:
```json
{"role": "system", "content": "中央大學"}
{"role": "system", "content": "台灣大學"}
{"role": "system", "content": "成功大學"}
{"role": "system", "content": "中原大學"}
{"role": "system", "content": "健行科技大學"}
{"role": "system", "content": "台北海洋大學"}
{"role": "system", "content": "中山大學"}
```