44

この変換テーブルによると、JSON モジュールを使用してシリアライズすると、Python の int は 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

なぜこれが起こるのですか? キーを数値として強制的に書き込む方法はありますか?

4

3 に答える 3

49

単純な理由は、JSON では整数キーを使用できないためです。

object
    {}
    { members } 
members
    pair
    pair , members
pair
    string : value  # Keys *must* be strings.

この制限を回避する方法については、まず、受信側の実装が技術的に無効な JSON を処理できることを確認する必要があります。その後、すべての引用符を置き換えるか、カスタム シリアライザーを使用できます。

于 2013-06-14T00:58:18.667 に答える
1

この関数は、可能であれば、すべての文字列キーを int キーに再帰的にキャストします。不可能な場合、キー タイプは変更されません。

以下の JLT の例を少し調整しました。私の巨大なネストされた辞書のいくつかでは、そのコードが辞書のサイズを変更し、例外で終了しました。とにかく、クレジットは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
于 2019-04-25T05:53:19.303 に答える