为什么在使用 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
Why do int keys of a python dict turn into strings when using json.dumps?
提问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

