JSONでPythonタプルを保持するには?pickleと独自エンコーダーの実装方法
JSONにはタプルの概念が存在しない
JSONフォーマットには、タプルというデータ型が存在しません。そのため、Pythonの標準ライブラリであるjsonモジュールは、PythonのタプルをJSONの配列(リスト)に変換して処理します。これは、JSONの中でタプルに最も近いデータ構造が配列だからです。
しかし、この変換によってタプル本来の特性である「イミュータブル(変更不可)」という性質は失われます。JSON化した時点で、元のデータがタプルだったのかリストだったのかを区別する情報は残らないのです。
タプルを保持するための主な方法
1. pickleモジュールを使う
pickleを使えば、Pythonオブジェクトをそのままの形で保存できます。ただし、pickleで保存されるのは.jsonファイルではなく.pklファイルであり、JSONファイルとしては扱えません。さらに、pickleはPython固有のシリアライズ形式のため、Web APIなど異なる言語・環境間でデータをやり取りする用途には不向きです。信頼できないデータを読み込む際のセキュリティリスクにも注意が必要です。
2. 独自のエンコーダー・デコーダーを実装する
最も柔軟で実用的なのが、独自のエンコーダーとデコーダーを作成する方法です。タプルを識別できるマーカー付きの形式でJSONに出力し、読み込み時にそのマーカーを検知してタプルへ復元することで、リストとタプルを区別したままデータを保持できます。
import json
class TupleEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, tuple):
return {"__tuple__": True, "items": list(obj)}
return super().default(obj)
def as_tuple(dct):
if dct.get("__tuple__"):
return tuple(dct["items"])
return dct
data = (1, 2, 3)
encoded = json.dumps(data, cls=TupleEncoder)
decoded = json.loads(encoded, object_hook=as_tuple)
print(decoded) # (1, 2, 3)
まとめ
JSON単体ではタプルの性質を保持できません。ローカル環境での保存が目的ならpickle、Webを介したデータ交換が目的なら独自のエンコーダー・デコーダーの実装がベストプラクティスです。用途に応じて適切な方法を選択しましょう。
-
TensorFlowを使ってPythonで文字列の部分文字列(サブストリング)を操作する方法
TensorFlowでは、「strings」モジュールに用意されている「substr」メソッドを使うことで、文字列の部分文字列(サブストリング)を簡単に扱うことができます。処理結果はNumPy配列に変換したうえで表示されます。 関連記事:TensorFlowとは何か?KerasがTensorFlowと連携してニューラルネットワークを構築する仕組みを解説 本記事では、PythonでUnicode文字列を表現する方法と、Unicode対応の操作を使ってそれらを加工する方法を学びます。まず、標準的な文字列操作に相当するUnicode版の関数を活用し、文字体系(スクリプト)の検出に基づいてUnicod
-
PythonのBokehライブラリでグリッドプロットを作成する方法
Bokehは、データ可視化を支援するPythonパッケージです。オープンソースプロジェクトとして公開されており、HTMLとJavaScriptを使ってプロットを描画します。この特性により、Webベースのダッシュボードを構築する際に特に有用です。Bokehの仕組みBokehはデータソースをJSONファイルへと変換します。このJSONファイルは、JavaScriptライブラリであるBokehJSへの入力として利用されます。BokehJSはTypeScriptで記述されており、最新のブラウザ上で可視化をレンダリングすることを可能にしています。Bokehの依存ライブラリNumpyPillowJinja