Python json模块生成非唯一键

时间:2018-01-27 17:14:22

标签: python json

根据JSON规范https://tools.ietf.org/html/rfc8259,对象的键应该是唯一的

  
      
  1. 物件

         

    对象结构表示为一对花括号
      包含零个或多个名称/值对(或成员)。名字是一个   串。每个名称后面都有一个冒号,分隔名称
      从价值。单个逗号将值与后续值分开   名称。 对象中的名称应该是唯一的

  2.   

但是可以使用两个相同的键创建json对象

Python 3.5.2 (default, Nov 23 2017, 16:37:01) 
[GCC 5.4.0 20160609] on linux
>>> import json
>>> json.dumps({1: 'value1', "1": 'value2'})
'{"1": "value1", "1": "value2"}'

这是一个错误吗?

2 个答案:

答案 0 :(得分:4)

JSON spec中,对象(如dict)是:

  

对象结构表示为一对花括号      包含零个或多个名称/值对(或成员)。 名字是      字符串。

强调我的。 Python json.dumps对输入对象非常宽容。它会隐式地将整数键转换为字符串,这可能会导致数据丢失/键冲突,就像您一样。在这里见过。它也打破了往返loads(dumps(d))

如果您的上下文中存在数据丢失问题,请考虑使用更严格的json库,例如

>>> import demjson  # pip install demjson
>>> demjson.encode({1: 'value1', "1": 'value2'}, strict=True)
# JSONEncodeError: ('object properties (dictionary keys) must be strings in strict JSON', 1)
  

是错误吗?

在我看来,是的。我已经看到了很多由此引起的错误,并且如果默认情况下stdlib json.dumps是严格的,并且使用 opt-in 关键字参数来启用任何隐式转换,则更愿意。但是,在Python中改变这种情况的几率几乎为零。

答案 1 :(得分:3)

JSON RFC说"密钥应该是唯一的。" RFC对于"应该具有非常特殊的含义。""来自https://tools.ietf.org/html/rfc2119

  

应该:这个词,或形容词"推荐",表示那里      在特定情况下可能存在有效理由忽略a      特殊项目,但必须理解全部含义      在选择不同的课程之前仔细权衡。

所以JSON不被禁止有重复的密钥,虽然这是不可取的,我建议反对它。

如果你想检查你的词典是否合适,你可以使用这个测试:

def keys_are_unique(d):
    return len(d) == len(set(str(k) for k in d))