Werner Venter
Werner Venter

Reputation: 57

Python3 Nested Dictionary Overwrite

I am loading two dictionaries from JSON files

# var_dict_config
{
     "application" : {
          "alias" : "process-io-y",

          "version" : "10.5.0.17 - Ghost Revision: 10",

          "log_level" : "debug",
          "log_file"  : "log/debug.log",

          "application_startup_delay" : "0"
     },
     "io" : {
          "io_mode" : "gpio.bcm",
          "io_warnings" : "on",

          "io_startup_test" : "on",

          "mapping" : {
               "io_01" : {
                    "pin"   : "05",
                    "mode"  : "output",
                    "state" : "off",
                    "lockout" : "off"
               },
               "io_02" : {
                    "pin"   : "06",
                    "mode"  : "output",
                    "state" : "off",
                    "lockout" : "off"
               }
          }
     }
}





# var_dict_config_overwrite
{
     "application" : {
          "alias"  : "bare-y",
          "version" : "xxxx"
     },
     "io" : {
          "io_mode" : "gpio.bcm",
          "io_warnings" : "xxxxx",

          "io_startup_test" : "xxxxx"
          }
     }
}

I would like to copy the values from var_dict_config_overwrite to var_dict_config

The code below works but not for nested dictionaries

     var_dict_config = {**var_dict_config, **var_dict_config_overwrite}

At the moment I am doing this

     var_dict_config['application'] = {**var_dict_config['application'], **var_dict_config_overwrite['application']}

Is there a more elegant way of doing this?

Upvotes: 1

Views: 116

Answers (1)

S.B
S.B

Reputation: 16476

For test to be complete, I've added two different key named "addition1" and "addition2" in two different location in var_dict_config_overwrite dictionary.

So here is you dictionaries :

var_dict_config = {
    "application": {
        "alias": "process-io-y",

        "version": "10.5.0.17 - Ghost Revision: 10",

        "log_level": "debug",
        "log_file": "log/debug.log",

        "application_startup_delay": "0"
    },
    "io": {
        "io_mode": "gpio.bcm",
        "io_warnings": "on",

        "io_startup_test": "on",

        "mapping": {
            "io_01": {
                "pin": "05",
                "mode": "output",
                "state": "off",
                "lockout": "off"
            },
            "io_02": {
                "pin": "06",
                "mode": "output",
                "state": "off",
                "lockout": "off"
            }
        }
    }
}


var_dict_config_overwrite = {
    "application": {
        "alias": "bare-y",
        "version": "xxxx"
    },
    "io": {
        "io_mode": "gpio.bcm",
        "io_warnings": "xxxxx",

        "io_startup_test": "xxxxx",
        "addition1": {"addition1": "foo1",
                      "addition2": "foo2"}
    },
    "addition2": {"addition2": "foo2",
                  "addition3": "foo3"}
}

You can achieve this with a recursive merger function like this :

def recursive_merge(d1, d2):
    for k, v in d2.items():
        if k in d1:
            if isinstance(v, dict):
                recursive_merge(d1[k], v)
            else:
                d1[k] = v
        else:
            d1[k] = v
    return d1


for k, v in recursive_merge(var_dict_config, var_dict_config_overwrite).items():
    print(k, v)

It works with any levels of nested dictionaries.

Upvotes: 2

Related Questions