Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Converting JSON data to Python object while ignoring Lists

Tags:

python

json

I have JSON file that contains the structure of neural networks. I would like to convert the JSON file to an object, but, if possible, ignore the lists.

For example, this is the content of the JSON file:

{
  "name": "model_6",
  "network": {
    "input_shape": [3],
    "output_shape": [9, 50],
    "layers": [
      {"type": "Linear", "in_features": 3, "out_features": 1024},
      {"type": "ReLU"},
      {"type": "View", "shape": [-1, 16, 64]},
      {"type": "Conv1d", "in_channels": 16, "out_channels": 32, "kernel_size": 3, "padding":0, "dilation":2},
      # ...
    ]
  }
}

And I would like to be able to access like an object, e.g. config.network.layers but having the list not converted into an object. Therefore, for example,

print(config.network.layers)

would give me :

[
  {"type": "Linear", "in_features": 3, "out_features": 1024},
  {"type": "ReLU"},
  {"type": "View", "shape": [-1, 16, 64]},
  {"type": "Conv1d", "in_channels": 16, "out_channels": 32, "kernel_size": 3, "padding":0, "dilation":2}
  # ...
]

I tried using the solution using SimpleNamespace:

import json
from types import SimpleNamespace

with open('model.json') as f:
    config = json.loads(f.read(), object_hook=lambda d: SimpleNamespace(**d))

But it is really not that convenient for my application because what is inside the list also get converted into object and it messes up with other parts of the code

like image 692
th0mash Avatar asked Apr 16 '26 04:04

th0mash


1 Answers

If I understand correctly, the issue is to convert a nested dict into dot-accessible nested objects.

You can use the famous Bunch pattern to turn a dict into a dot-accessible object:

class Bunch(object):
    def __init__(self, adict):
        self.__dict__.update(adict)

And then use it recursively for the nested dicts:

def to_bunch(d):
    if isinstance(d, dict):
        return Bunch({k: to_bunch(v) for k, v in d.items()})
    return d

Usage example:

d = json.loads("""
{
  "name": "model_6",
  "network": {
    "input_shape": [3],
    "output_shape": [9, 50],
    "layers": [
      {"type": "Linear", "in_features": 3, "out_features": 1024},
      {"type": "ReLU"},
      {"type": "View", "shape": [-1, 16, 64]},
      {"type": "Conv1d", "in_channels": 16, "out_channels": 32, "kernel_size": 3, "padding":0, "dilation":2}
    ]
  }
}
""")

Then:

>>> config = to_bunch(d)
... config.network.layers
[{'type': 'Linear', 'in_features': 3, 'out_features': 1024},
 {'type': 'ReLU'},
 {'type': 'View', 'shape': [-1, 16, 64]},
 {'type': 'Conv1d',
  'in_channels': 16,
  'out_channels': 32,
  'kernel_size': 3,
  'padding': 0,
  'dilation': 2}]

Bonus: in an interactive environment, you get tab-completion! (E.g. start with config. and hit <TAB>, and it will show you name and network, etc.)

like image 181
Pierre D Avatar answered Apr 18 '26 16:04

Pierre D



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!