flattening a dict

Terry Jones terry at jon.es
Sun Feb 17 07:18:59 EST 2008


Hi Arnaud & Benjamin

Here's a version that's a bit more general. It handles keys whose values
are empty dicts (assigning None to the value in the result), and also dict
keys that are not strings (see the test data below). It's also less
recursive as it only calls itself on values that are dicts.

But.... it returns a dict whose keys are tuples. You then need to decide
what to do with this. Hence the helper function strdictflatten for the case
when all dict keys can be converted to str.

As I told Arnaud in email, I greatly prefer his version for its elegance.

Terry


def dictflatten(d, prefix=None):
    result = {}
    if prefix is None: prefix = tuple()
    for k, v in d.iteritems():
        key = prefix + (k,)
        if isinstance(v, dict):
            if v:
                result.update(dictflatten(v, key))
            else:
                result[key] = None
        else:
            result[key] = v
    return result

def strdictflatten(d, sep='/'):
    return dict((sep.join(map(str, k)), v) for k, v in dictflatten(d).iteritems())
    
if __name__ == '__main__':
    test = {
        "" : {},
        4 : 5,
        "mays" : {"eggs" : "spam"},
        "jam" : {"soda" : {"love" : "dump"}},
        "lamba" : 23
        }

    d = dictflatten(test)
    print strdictflatten(test)

>>>> {'': None, 'lamba': 23, 'mays/eggs': 'spam', '4': 5, 'jam/soda/love': 'dump'}



More information about the Python-list mailing list