flattening a dict

Benjamin musiccomposition at gmail.com
Thu Feb 21 20:04:29 EST 2008


On Feb 17, 6:18 am, Terry Jones <te... at jon.es> wrote:
> 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())
Thanks. This is great. Now, how would I restrict the depth of the
flattening? For example, what if I just wanted something like this:
{
"mays" : {"eggs" : "spam"},
"jam" : {"soda" : "soda/love" : "dump"},
lamba" : 23
}
They are left alone up the to second level of recursion.
> 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