-3

Given a nested dictionary:

nested = {
    'A': {
        'B': {
            'C': 'C val',
            'G': 'G val'
        },
        'D': {
            'E': {
                'F': 'F val'
            }
        }
    }
}

I want to recursively concatenate the keys of the dictionary, except for the "final" key-value pairs, and put the concatenated keys in a new dictionary, like so:

expected = { 'A:B': {'C': 'C val', 'G': 'G val'}, 'A:D:E': {'F': 'F val'} }

How can I make such a function, without knowing the structure of the nested dict beforehand?

fredtantini
  • 15,966
  • 8
  • 49
  • 55
kwargs
  • 13
  • 4
  • 1
    You will have to write a function. Check http://stackoverflow.com/questions/6027558/flatten-nested-python-dictionaries-compressing-keys or http://stackoverflow.com/a/3835252/3336968 for a start – fredtantini Oct 01 '14 at 15:26

1 Answers1

1

A recursive solution is the simplest. This code does as you ask.

def flatten(dictionary, prefix=[], result={}):

    for k, v in dictionary.iteritems():
        type_v = type(v)
        if type_v == dict:
            flatten(v, prefix+[k], result)
        elif type_v == str:
            prefix_str = ':'.join(prefix)
            if not prefix_str in result:
                result[prefix_str] = {}
            result[prefix_str][k] = v
        else:
            raise TypeError('%s not permissible in data structure' % type_v)

    return result


nested = {
    'A': {
        'B': {
            'C': 'C val',
            'G': 'G val',
        },
        'D': {
            'E': {
                'F': 'F val',
            }
        }
    }
}

expected = flatten(nested)
print(expected)

output

{'A:B': {'C': 'C val', 'G': 'G val'}, 'A:D:E': {'F': 'F val'}}
Borodin
  • 126,100
  • 9
  • 70
  • 144
  • Thank you! I was over-thinking the problem, but you solved it by passing `prefix` as a function parameter. I also changed the default values of `prefix` and `result` as mentioned [here](http://stackoverflow.com/a/9526480/4099278). – kwargs Oct 02 '14 at 10:10