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

时间:2013-06-14 00:56:42

标签: python json serialization

根据this conversion table,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

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

3 个答案:

答案 0 :(得分:35)

简单的原因是JSON does not allow integer keys.

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

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

答案 1 :(得分:0)

如果确实需要,您可以使用以下方法检查键是否可以再次转换为整数:

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

答案 2 :(得分:0)

如果可能,此函数将所有字符串键递归转换为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