为什么在使用 json.dumps 时,python dict 的 int 键会变成字符串?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17099556/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 00:27:44  来源:igfitidea点击:

Why do int keys of a python dict turn into strings when using json.dumps?

pythonjsonserialization

提问by jveldridge

According to this conversion table, Python ints get written as JSON numbers when serialized using the JSON module--as I would expect and desire.

根据这个转换表,当使用 JSON 模块序列化时,Python 整数被写为 JSON 数字——正如我所期望和希望的。

I have a dictionary with an integer key and integer value:

我有一个带有整数键和整数值的字典:

>>> d = {1:2}
>>> type(d.items()[0][0])
<type 'int'>
>>> type(d.items()[0][1])
<type 'int'>

When I use the json module to serialize this to a JSON string, the value is written as a number, but the key is written as a string:

当我使用 json 模块将其序列化为 JSON 字符串时,值写为数字,但键写为字符串:

>>> json.dumps(d)
'{"1": 2}'

This isn't the behavior I want, and it seems particularly broken since it breaks json.dumps/json.loads round-tripping:

这不是我想要的行为,它似乎特别坏,因为它破坏了 json.dumps/json.loads 往返:

>>> d == json.loads(json.dumps(d))
False

Why does this happen, and is there a way I can force the key to be written as a number?

为什么会发生这种情况,有没有办法强制将密钥写为数字?

采纳答案by Sean Vieira

The simple reason is that JSON does not allow integer keys.

原因很简单,JSON 不允许整数键。

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

As to how to get around this limitation - you will first need to ensure that the receiving implementation can handle the technically-invalid JSON. Then you can either replace all of the quote marks or use a custom serializer.

至于如何绕过这个限制 - 您首先需要确保接收实现可以处理技术上无效的 JSON。然后您可以替换所有引号或使用自定义序列化程序。

回答by JLT

If you really want to, you can check keys for being convertable to integers again using:

如果你真的想要,你可以使用以下方法检查键是否可以再次转换为整数:

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

回答by Jonas Melin

This function will recursively cast all string-keys to int-keys, if possible. If not possible the key-type will remain unchanged.

如果可能,此函数将递归地将所有字符串键转换为整数键。如果不可能,密钥类型将保持不变。

I adjusted JLT'sexample below slightly. With some of my huge nested dictionaries that code made the size of the dictionary change, ending with an exception. Anyhow, credit goes to JLT!

我稍微调整了下面的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