PythonでJSONを弄りたい
ふっちーです。よろしくお願いします。
現在python3エンジニア認定基礎試験の資格を取得するため、日々勉強に励んでいます。
資格の参考書として使用しているPythonチュートリアルの中で、手間取ったところ書いてみます。
環境
今回はGoogle Colabolatory(Colab)を使用しました。
colab.research.google.com
実践
準備
まず、作業ディレクトリを作ります。
Colabではコマンドの先頭に!
をつけることでLinuxコマンドを実行できます。
!mkdir work
辞書型データの作成
まず、Pythonで辞書型(Dict)のデータを作ります。
2種類の方法で作ってみました。
①数値をKeyにする
HutoRider = {} memory = ['cyclone', 'joker', 'heat', 'metal', 'luna', 'trigger', 'fang', 'xtreme', 'prizm', 'accel', 'engine', 'trial'] for index, value in enumerate(memory): HutoRider[index] = value print(HutoRider)
出力結果: {0: 'cyclone', 1: 'joker', 2: 'heat', 3: 'metal', 4: 'luna', 5: 'trigger', 6: 'fang', 7: 'xtreme', 8: 'prizm', 9: 'accel', 10: 'engine', 11: 'trial'}
enumerate関数を使って、リストの先頭から順にインデックスを振りました。
enumerate関数は引数の要素と、そのインデックス値を同時に返してくれます。
②文字(列)をKeyにする
T2memories = {} AtoZ = [chr(i) for i in range(ord('A'), ord('Z')+1)] #ordでascIIコード化 print(AtoZ) AtoZvalue = ['アクセル','バード', 'サイクロン', 'ダミー', 'エターナル', 'ファング', 'ジーン', 'ヒート', 'アイスエイジ', 'ジョーカー', 'キー', 'ルナ', 'メタル', 'ナスカ', 'オーシャン', 'パペティア', 'クイーン', 'ロケット', 'スカル', 'トリガー', 'ユニコーン', 'バイオレンス', 'ウェザー', 'エクストリーム', 'イエスタディ', 'ゾーン'] for alphabet, value in zip(AtoZ, AtoZvalue): T2memories[alphabet] = value print(T2memories)
出力結果: ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'] {'A': 'アクセル', 'B': 'バード', 'C': 'サイクロン', 'D': 'ダミー', 'E': 'エターナル', 'F': 'ファング', 'G': 'ジーン', 'H': 'ヒート', 'I': 'アイスエイジ', 'J': 'ジョーカー', 'K': 'キー', 'L': 'ルナ', 'M': 'メタル', 'N': 'ナスカ', 'O': 'オーシャン', 'P': 'パペティア', 'Q': 'クイーン', 'R': 'ロケット', 'S': 'スカル', 'T': 'トリガー', 'U': 'ユニコーン', 'V': 'バイオレンス', 'W': 'ウェザー', 'X': 'エクストリーム', 'Y': 'イエスタディ', 'Z': 'ゾーン'}
1つ目の出力結果はAtoZ、2つ目の出力結果はT2memoriesです。
AtoZはリスト内包でAからZのリストを作成しています。
以下でも同じ結果が得られます。
AtoZ=[] for i in range(ord('A'), ord('Z')+1): AtoZ.append(chr(i))
こちらはzip関数を使って、2つのリストの先頭から一つずつ取り出してKeyとValueにしています。
zip関数でまとめるリストは同じ長さである必要があります。
JSONファイルの作成
先ほど作った辞書型のデータを使ってjsonファイルを作ってみます。
辞書型のデータをJSON形式に変換するには、jsonモジュールのdumpメソッドを使います。
このJSONデータをファイルに書き込みたいので、書き込みモード(w)でopenしておきます。
import json with open('./work/RiderMemory.json', 'w') as f: json.dump(HutoRider, f) with open('./work/T2Memories.json', 'w') as f: json.dump(T2memories, f)
これでJSONファイルが2つ出来ました。結構あっさりですね。
中身の確認
きちんとファイルに書き込めているでしょうか。
ファイルを開いて確認してみます。
f = open('./work/RiderMemory.json','r') Riderdir = json.load(f) print(Riderdir)
出力結果: {'0': 'cyclone', '1': 'joker', '2': 'heat', '3': 'metal', '4': 'luna', '5': 'trigger', '6': 'fang', '7': 'xtreme', '8': 'prizm', '9': 'accel', '10': 'engine', '11': 'trial'}
大丈夫そうで・・・あれ?
ファイルに書き込む前の辞書型データをもう一度見てみましょう。
たしか、こんな感じでした。
{0: 'cyclone', 1: 'joker', 2: 'heat', 3: 'metal', 4: 'luna', 5: 'trigger', 6: 'fang', 7: 'xtreme', 8: 'prizm', 9: 'accel', 10: 'engine', 11: 'trial'}
JSON形式に変換したデータは、キーの数字がシングルクォートで囲まれています!
これは、Pythonではキーに文字列以外の値(今回は数値)を使えますが、JSONでは文字列に限定されているためです。
辞書型のデータのKeyに文字列以外が入っていると、JSONに変換した際に文字列に変換されます。
もう少し見やすくしたい
ところで、普通に出力すると見にくいですね・・・。
折角なので、もう少し見やすくしてみましょう。
RiderStr = json.dumps(Riderdir, indent = 4) print(RiderStr)
出力結果: { "0": "cyclone", "1": "joker", "2": "heat", "3": "metal", "4": "luna", "5": "trigger", "6": "fang", "7": "xtreme", "8": "prizm", "9": "accel", "10": "engine", "11": "trial" }
Key:Valueの単位で改行が入り、見やすくなりましたね。
json.dumps()
で文字列化した際にindent=4
とすることで、空白スペース4つ分のインデントが入りました。
文字化けするとき
json.dumps()
で文字化けしてしまう場合、dumpsメソッドの引数にensure_ascii=False
を追加するとうまく動いてくれます。
T2Str = json.dumps(T2dir, ensure_ascii=False, indent = 4) print(T2Str)
出力結果: { "A": "アクセル", "B": "バード", "C": "サイクロン", "D": "ダミー", "E": "エターナル", "F": "ファング", "G": "ジーン", "H": "ヒート", "I": "アイスエイジ", "J": "ジョーカー", "K": "キー", "L": "ルナ", "M": "メタル", "N": "ナスカ", "O": "オーシャン", "P": "パペティア", "Q": "クイーン", "R": "ロケット", "S": "スカル", "T": "トリガー", "U": "ユニコーン", "V": "バイオレンス", "W": "ウェザー", "X": "エクストリーム", "Y": "イエスタディ", "Z": "ゾーン" }
ソートする
辞書型のデータのKeyの順番を変えます。
今までの辞書型はKeyを軸に並んでいたので、Valueを軸に並び変えてみます。
RiderSort = sorted(Riderdir.items(), key=lambda x: x[1]) print(RiderSort)
出力結果: [('9', 'accel'), ('0', 'cyclone'), ('10', 'engine'), ('6', 'fang'), ('2', 'heat'), ('1', 'joker'), ('4', 'luna'), ('3', 'metal'), ('8', 'prizm'), ('11', 'trial'), ('5', 'trigger'), ('7', 'xtreme')]
Valueがアルファベット順に並びました!
今回のキーはlambda式ですね。(Keyだけに)
lambda式は無名関数と呼ばれ、lambda 引数: 処理
と書きます。
まとめ
今回はJSONの扱いを通して、以下の内容を学びました。
・enumerate
・zipメソッド
・リスト内包
・lambda式