JSONと辞書型（ディクショナリー）の違い

# はじめに

こんにちは、よわよわエンジニアです。

本稿では、超よわよわだった当時の自分に向けて、JSONと辞書型の違いを説明します。
あくまでも "違い" にフォーカスして解説しますので、JSONと辞書型それぞれの詳細な説明は他の記事をご参照ください。

ちなみに、Pythonでは「辞書型」と言いますが、他の言語では「オブジェクト型」や「連想配列」、「ハッシュテーブル」と言ったりしますね。
ここからは「辞書型」と呼称を統一し、Pythonのコードベースで説明していきます。


# JSONと辞書型の違いが理解できなかった
プログラミングを学びたてだった当時、私は「辞書型」→「JSON」の順でこれらを知ることになりますが、長らくその違いを理解することができませんでした。

Pythonを学び始めてまずは「辞書型」を知り、以下のようなコードで「ふんふん…こんな感じね」と理解します。

```python:python
d = {"name": "Taro", "age": 12, "country": "Japan"}
print(d)
# {'name': 'Taro', 'age': 12, 'country': 'Japan'}
```



その後、Webの勉強をし始めた私は「JSON」と出会います。
[Wikipedia](https://ja.wikipedia.org/wiki/JavaScript_Object_Notation)で以下のように説明がある通り、私が当時読んだ記事にも「JSONはデータフォーマットの一種である」と記載されていました。

> JavaScript Object Notation（JSON、ジェイソン）はデータ記述言語の1つである。軽量なテキストベースのデータ交換用フォーマットでありプログラミング言語を問わず利用できる

そして、JSONで表記されたデータ構造の具体例として以下のような記載があったのですが...


```:JSON
{
    "name": "Taro",
    "age": 12,
    "country": "Japan"
}
```

「辞書型を`print`したものと一緒じゃねーか！ 何が違うんだあああ...」


# JSONと辞書型は何が違うのか

## 結論
JSONは「データフォーマット」であり、辞書型は「Pythonにおけるデータ型の一種」です。

JSONというフォーマットに従って記述されたデータは、そのままでは構造化された情報へのアクセスが容易に行えません。
なぜなら、ただの文字列だからです。

`d["key名"]`のような形でデータにアクセスできるようにするには、それぞれのプログラミング言語に応じて適切なデータ型に変換してあげる必要があります。
それが**Pythonでは辞書型**であり、JavaScirptではオブジェクト型に該当する訳です。

|![スクリーンショット 2021-11-23 18.05.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1047806/47d7cff7-25fe-06c6-9440-2fb290b22db8.png)|
|:-:|

## JSONは「データフォーマット」

JSONは「こういうルールで書きましょうね」というただのフォーマットです。

似たものにCSVがありますが、CSVでは以下のように「カンマ区切りで書きましょう」というルールに基づいてデータを表現しますよね。

```:csv
name, age, country
Taro, 12, Japan
```

一方でJSONでは、「`{}`（波括弧）で囲みましょう」であったり「文字列は必ず`""`（ダブルクオーテーション）で囲みましょう」といったルールが定められており、そのルールに基づいて以下のようにデータを表現します。

```:JSON
{
    "name": "Taro",
    "age": 12,
    "country": "Japan"
}
```

つまり、あえて誤解を恐れずに言うと、**JSONはただの「文字列」**です。

以下の例では、`json_text` という変数に、JSON形式の文字列を代入しています。

```python:python
json_text = '{"name": "Taro", "age": 12, "country": "Japan"}'
print(type(json_text))
# <class 'str'>
```

せっかくの構造化されたデータなので、`json_text["name"]` のような形で値を取得したくなりますよね。
しかし、そんなことは出来ません。なぜなら`json_text`は`str`型のただの文字列だからです。

```python:python
print(json_text["name"])
# 以下のエラーが出力され、値は取得できない
# Traceback (most recent call last):
#  File "<stdin>", line 1, in <module>
# TypeError: string indices must be integers
```

`json_text["name"]`といった形でデータを取り扱いたい場合、Pythonでは「辞書型」に変換することでこれを実現します。

## 辞書型は「データ型」

一方で辞書型はPythonで扱えるデータ型の一種です。
Pythonでは`int`型、`str`型など様々なデータ型がありますが、その一つが`dict`型（辞書型）です。

辞書型はさまざまな便利機能をもっており、`d["key名"]`とすることで値を取得できたり、`d.keys()`とすることでkeyの一覧を取得できたりします。

Pythonでは、JSON形式で記述されたデータ（文字列）をこの辞書型に変換することで、辞書型のさまざまな便利機能を使ってデータをより柔軟に取り扱うことが出来るようになります。

変換に際しては、`json`というモジュールを使います。

```python:python
import json

json_text = '{"name": "Taro", "age": 12, "country": "Japan"}'
d = json.loads(json_text)

print(type(d))
# <class 'dict'>

print(d["name"])
# Taro
```

`str`型である `json_text` を `json.loads()` という関数で変換することで`dict`型（辞書型）になり、`d["name"]`という形で値を取得できているのがわかります。

また当然ですが、辞書型からJSON形式の文字列に変換することも可能です。
その際は、`json.dumps()`に辞書型のデータを渡すことで実現できます。

# まとめ

本稿のまとめです。

- JSONと辞書型の違い
  - JSONはデータフォーマット
  - 辞書型はPythonにおけるデータの型
- JSON形式のデータはただの文字列なので、それぞれのプログラミング言語で適切なデータ型に変換することで扱いが容易になる

# 参考文献
- [JavaScript Object Notation - Wikipedia](https://ja.wikipedia.org/wiki/JavaScript_Object_Notation)