1

I know that each JSON data coming to my deserializer has integer_string key type and I want to convert to python dict with integer keys during deserialization for performance efficiency. I don't want to deserialize it to dict and after that one more time iterate over nested dict in order to change the key types! So wandering if python's standard JSON library or maybe some other json library could natively support some input parameter in order to convert keys strings to the dictionary with integer keys

{"1": "data_1", "2": "data_2"...}

Please note my json could be nested like {"1": "data_1", "2": "{"3": "data_3"}"...}

David Mnatsakanyan
  • 455
  • 1
  • 4
  • 15

1 Answers1

2

While Python supports dictionary keys of an arbritary type, JSON does not. The JSON spec clearly states that keys must be strings. Thus, any library that decodes JSON will not have an option to attempt to decode keys as another type (such as a numnber).

However it is easy to to this yourself from Python.


json_Str = '{"1": "foo", "2": "bar"}'

if __name__ == '__main__':
    x = json.loads(json_Str)
    result = {}
    for k, v in json.loads(json_Str).items():
        try:
            as_int = int(k)
            result[as_int] = v
        except ValueError:
            result[k] = v

    print(result)
    assert(type(result.keys()[0]) is int)

   

If you need to do this on multiple JSON structures, then you can also make your own custom decoding hook. This will allow you to add the ability for "Python to support JSON interger keys".

This approach also replaces the dictionary keys in place, which is slightly more memory efficient if you are working with large datasets.

import json

json_Str = '{"1": "foo", "2": "bar", "4": [1, 2, 3]}'


def int_key_hook(obj):
    if type(obj) is not dict:
        return obj

    for key in obj.keys():
        try:
            as_int = int(key)
            obj[as_int] = obj[key]
            del obj[key]
        except ValueError:
            pass

    return(obj)


my_decoder = json.JSONDecoder(object_hook=int_key_hook)



if __name__ == '__main__':
    x = my_decoder.decode(json_Str)

    print(x)
    assert(type(x.keys()[1]) is int)
Brian H.
  • 2,092
  • 19
  • 39
  • Wondering if python natively supports integer keys for dicts why pythone's json library should not support this feature ? – David Mnatsakanyan Aug 06 '19 at 14:07
  • @DavidMnatsakanyan JSON is not specific to python, it is a universal data structure format. And thus if one JSON library does not support a specific feature (because of the limitations of JSON itself), then any other JSON library won't support that feature!! – WiseDev Aug 06 '19 at 14:15
  • @DavidMnatsakanyan I updated my answer to provide an alternative that allows you to add this type of custom parsing directly to `JSONDecoder`. Also to ellaborate on BlueRine's point. JSON stands for "*JavsScript* Object Notation. It was originally designed to be used only with JavaScript as a way to seralize objects. The designer made an explicit choice to only support string-based keys, as there was a lot of confusion and bad code practices surrounding JavaScript's object/dictionaries at the time. It wasn't until later that the rest of the programming world started using JSON. – Brian H. Aug 06 '19 at 14:25
  • Thanks for the clarification ) – David Mnatsakanyan Aug 06 '19 at 14:33