On Feb 17, 12:18 pm, Terry Jones <[EMAIL PROTECTED]> 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
It's nice to do it this way I think. Here I post a generator-powered version of the same idea. from itertools import chain def flattendict(d): def gen(d, pfx=()): return chain(*(gen(v, pfx+(k,)) if isinstance(v, dict) else ((pfx+(k,), v),) for k, v in d.iteritems())) return dict(gen(d)) BTW, I keep using the idiom itertools.chain(*iterable). I guess that during function calls *iterable gets expanded to a tuple. Wouldn't it be nice to have an equivalent one-argument function that takes an iterable of iterables and return the 'flattened' iterable? -- Arnaud -- http://mail.python.org/mailman/listinfo/python-list