この変換テーブル 、Python intsはJSONモジュールを使用してシリアル化されるとJSON番号として書き込まれます。
私は整数キーと整数値を持つ辞書を持っています:
>>> d = {1:2}
>>> type(d.items()[0][0])
<type 'int'>
>>> type(d.items()[0][1])
<type 'int'>
Jsonモジュールを使用してこれをJSON文字列にシリアル化すると、値は数値として書き込まれますが、キーは文字列として書き込まれます。
>>> json.dumps(d)
'{"1": 2}'
これは私が望んでいる動作ではなく、json.dumps/json.loadsのラウンドトリップを破壊するため、特に壊れているようです。
>>> d == json.loads(json.dumps(d))
False
なぜこれが起こるのですか?キーを数字として強制的に書き込む方法はありますか?
単純な理由は、 JSONは整数キーを許可しません。
object
{}
{ members }
members
pair
pair , members
pair
string : value # Keys *must* be strings.
この制限を回避する方法については、まず、受信側の実装が技術的に無効なJSONを処理できることを確認する必要があります。次に、すべての引用符を置き換えるか、カスタムシリアライザーを使用します。
この関数は、可能であれば、すべての文字列キーをintキーに再帰的にキャストします。不可能な場合、キータイプは変更されません。
JLT's 以下の例を少し調整しました。私の巨大なネストされた辞書のいくつかで、コードは辞書のサイズを変更し、例外で終了しました。とにかく、クレジットはJLTにあります!
def pythonify(json_data):
correctedDict = {}
for key, value in json_data.items():
if isinstance(value, list):
value = [pythonify(item) if isinstance(item, dict) else item for item in value]
Elif isinstance(value, dict):
value = pythonify(value)
try:
key = int(key)
except Exception as ex:
pass
correctedDict[key] = value
return correctedDict
本当にしたい場合は、キーをもう一度整数に変換できるかどうかを確認することができます:
def pythonify(json_data):
for key, value in json_data.iteritems():
if isinstance(value, list):
value = [ pythonify(item) if isinstance(item, dict) else item for item in value ]
Elif isinstance(value, dict):
value = pythonify(value)
try:
newkey = int(key)
del json_data[key]
key = newkey
except TypeError:
pass
json_data[key] = value
return json_data