skip to Main Content

I have a nested dictionary that I am trying to convert to JSON using json.dumps(unserialized_data), indent=2). The dictionary currently looks like this:

{
  "status": "SUCCESS",
  "data": {
    "cal": [
      {
        "year": 2022,
        "month": 8,
        "a": [
          {
            "a_id": 1,
            "b": [
              {
                "abc_id": 1,
                "val": 2342
              }
            ]
          }
        ]
      },
      {
        "year": 2022,
        "month": 9,
        "a": [
          {
            "a_id": 2,
            "b": [
              {
                "abc_id": 3,
                "val": 2342
              }
            ]
          }
        ]
      }
    ]
  }
}

How can I convert all integers of type int64 to int while leaving the structure of the dict and values of any other data type unaffected?

2

Answers


  1. If the only objects in your dict that aren’t JSON-serializable are all of type int64, you can easily serialize them by making int the default function for converting objects that JSON can’t serialize:

    json.dumps(unserialized_data, indent=2, default=int)
    
    Login or Signup to reply.
  2. If blhsing’s condition doesn’t apply, you can drill down recursively into the dictionary and cast any np.int64 to int:

    def cast_type(container, from_types, to_types):
        if isinstance(container, dict):
            # cast all contents of dictionary 
            return {cast_type(k, from_types, to_types): cast_type(v, from_types, to_types) for k, v in container.items()}
        elif isinstance(container, list):
            # cast all contents of list 
            return [cast_type(item, from_types, to_types) for item in container]
        else:
            for f, t in zip(from_types, to_types):
                # if item is of a type mentioned in from_types,
                # cast it to the corresponding to_types class
                if isinstance(container, f):
                    return t(container)
            # None of the above, return without casting 
            return container
    

    from_types and to_types are containers where corresponding elements give the type to convert from, and the type to convert to.
    Run your dictionary through this function, then dump it to json:

    import numpy as np
    import json
    
    d = {
      "str_data": "foo bar",
      "lst": [ np.int64(1000), np.float64(1.234) ],
      "dct": {"foo": "bar", "baz": np.float64(6.789), "boo": np.int64(10)}
    }
    
    print(json.dumps(d, indent=2)) # throws error
    
    print(json.dumps(
             cast_type(d, 
                 [np.int64, np.float64],
                 [int,      float]), 
             indent=2))
    

    Prints the dictionary as JSON:

    {
      "str_data": "foo bar",
      "lst": [
        1000,
        1.234
      ],
      "dct": {
        "foo": "bar",
        "baz": 6.789,
        "boo": 10
      }
    }
    

    Try online

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search