Philip
Philip

Reputation: 974

Python lookup dict and nested values in dict_keys and swap value

I'm attempting to swap values in dictionary(dic_map) with values from dictionary(B), where dic_map[key] = B. to give me a new dict with the values from B e.g

dic_map = {
    'Name': 'name',
    'Id': 'guid',
    'address':{
        'address1': 'road',
        'address2': 'road_nr',
        'address3': 'zipcode',
        'address4': 'city'
    },
    'tax': True,
    'isValid': False,
    'specific': 1,
    'credit': 200
}


B = {
    'name': 'Michael Jackson',
    'guid': '032-567-781',
    'road': 'The greatest Dr',
    'road_nr': 42,
    'zipcode': 90210,
    'city': 'Hollywood',
    'country': 'USA'
}

And the final dict

desired_result = {
    'Name': 'Michael Jackson',
    'Id': '032-567-781',
    'address':{
        'address1': 'The greatest Dr',
        'address2': 42,
        'address3': 90210,
        'address4': 'Hollywood',
    },
    'tax': True,
    'isValid': False,
    'specific': 1,
    'credit': 200
}

This is what I have so far

def swap_values(dic_values, dic_map):
    d = {}
    for k1 in dic_values.keys():
        for k2 in dic_map.keys():
            if k1 == dic_map[k2]:
                d[k2]=dic_values[k1]
            else:
                d[k2]=dic_map[k2]
    return d

There are 2 things that is not working as far as I can tell, 1. my values gets overwritten by the else statement, and 2. the nested dict is never evaluated. Any help would be appreciated.

Upvotes: 1

Views: 736

Answers (2)

bla
bla

Reputation: 1870

As there are inner dicts, we must repeat the replacement operation for every inner dict. The easiest way to perform that kind of task is using recursion.

Validating type is not considered very pythonic, but it will get the job done. You can do something like this:

def swap_values(dic_values, dic_map):
    d = {}

    for k, v in dic_values.items():
        if isinstance(v, dict):
            d[k] = swap_values(v, dic_map)
        else:
            d[k] = dic_map.get(v, v)

    return d

Sample usage:

>>> dic_map = {
...     'Name': 'name',
...     'Id': 'guid',
...     'address':{
...         'address1': 'road',
...         'address2': 'road_nr',
...         'address3': 'zipcode',
...         'address4': 'city'
...     },
...     'tax': True,
...     'isValid': False,
...     'specific': 1,
...     'credit': 200
... }
>>> 
>>> 
>>> B = {
...     'name': 'Michael Jackson',
...     'guid': '032-567-781',
...     'road': 'The greatest Dr',
...     'road_nr': 42,
...     'zipcode': 90210,
...     'city': 'Hollywood',
...     'country': 'USA'
... }
>>> swap_values(dic_map, B)
{'specific': 1, 'Name': 'Michael Jackson', 'credit': 200, 'address': {'address1': 'The greatest Dr', 'address2': 42, 'address4': 'Hollywood', 'address3': 90210}, 'isValid': False, 'tax': True, 'Id': '032-567-781'}

If there were no inner dicts, we could use:

def swap_values(dic_values, dic_map):
    d = {}

    for k, v in dic_values.items():
        d[k] = dic_map.get(v, v)

    return d

Sample usage:

>>> dic_map = {
...     'Name': 'name',
...     'Id': 'guid',
...     'tax': True,
...     'isValid': False,
...     'specific': 1,
...     'credit': 200
... }
>>> 
>>> 
>>> B = {
...     'name': 'Michael Jackson',
...     'guid': '032-567-781',
...     'road': 'The greatest Dr',
...     'road_nr': 42,
...     'zipcode': 90210,
...     'city': 'Hollywood',
...     'country': 'USA'
... }
>>> swap_values(dic_map, B)
{'specific': 1, 'isValid': False, 'Name': 'Michael Jackson', 'Id': '032-567-781', 'tax': True, 'credit': 200}

Upvotes: 1

TallChuck
TallChuck

Reputation: 1972

Here's what I got:

def dmap(template, values):
    for key, val in template.items():
        if isinstance(val, dict):
            dmap(val, values)
        else:
            if val in values:
                template[key] = values[val]

If I run dmap(dic_map, B) I get:

{
  'Id': '032-567-781',
  'Name': 'Michael Jackson',
  'address': {
    'address1': 'The greatest Dr',
    'address2': 42,
    'address3': 90210,
    'address4': 'Hollywood'
  },
  'credit': 200,
  'isValid': False,
  'specific': 1,
  'tax': True
}

Upvotes: 0

Related Questions