Home > Enterprise >  Python: How to ensure keys are type int
Python: How to ensure keys are type int

Time:07-13

In my code, I have a nested dictionary and I want to ensure that key id is an integer (note: it is a primary key). I tried just casting it to an int but I am unsure if the key is an int given that in the JSON there are double quotes.

See below my code and example of the data format.

statistics = defaultdict(dict)

\\in a loop
statistics[state][date].append({
                        int(id): {
                            "count_targets": targets,
                            "count_targets_excluded": excluded,
                            "count_targets_pending": pending,
                            "count_targets_in_progress": progress,
                            "count_targets_completed": completed,
                            "count_targets_failed": failed
                        }
                    })


{
  "stateA": {
    "2015-02-15": [
      {
        "13": {
          "count_targets": 5,
          "count_targets_excluded": 3,
          "count_targets_pending": 3,
          "count_targets_in_progress": 0,
          "count_targets_completed": 1,
          "count_targets_failed": 0
        }
      },
      {
        "14": {
          "count_targets": 4,
          "count_targets_excluded": 3,
          "count_targets_pending": 3,
          "count_targets_in_progress": 0,
          "count_targets_completed": 1,
          "count_targets_failed": 0
        }
      },

CodePudding user response:

JSON objects can only use JSON strings as keys:

>>> json.dumps({3: 4})
'{"3": 4}'

While the key in you dict is certainly an int, it gets converted to a string when encoding as JSON. JSON itself doesn't have a way of "remembering" the original type of the value used as a key, so you need some method (extra data in your JSON object, a pre-defined schema, etc) that the consumer of the JSON can use to turn the key back into an int after decoding.

CodePudding user response:

JSON can not have ints as keys thus your ints get cast as string as soon as you convert your dictionary to JSON.

CodePudding user response:

in the JSON there are double quotes.

You have what is called Object in JSON parlance, RFC7159 situplates that

An object structure is represented as a pair of curly brackets surrounding zero or more name/value pairs (or members). A name is a string.(...)

therefore, it will always have said quotes independently from type of key in python dict, consider that

import json
original = {1:100}
serialized = json.dumps(original)
deserialized = json.loads(serialized)
print(serialized)
print(original==deserialized)

gives output

{"1": 100}
False

CodePudding user response:

You can't produce legal JSON that has int keys, but if your goal is to parse incoming JSON with string keys that happen to represent valid ints (which you may or may not have generated in Python), and have them become true ints rather than str, you can do this:

def maybe_int(key):
    '''Converts strings that represent valid ints to int, leaving other strings unchanged'''
    try:
        return int(key)
    except ValueError:
        return key

def key_to_int(obj):
    '''Replaces all string keys representing valid ints with ints'''
    return {maybe_int(k): v for k, v in obj.items()}

 myjsonstr = '{"1": 2}'
 result = json.loads(myjsonstr, object_hook=key_to_int)

The hook is passed every decoded dict (aka JSON object), and that decoded dict is replaced by whatever the hook returns, in this case, a copy of the dict where any key that int can parse is replaced with its int value.

  • Related