flattening a dict
Arnaud Delobelle
arnodel at googlemail.com
Sun Feb 17 07:51:37 EST 2008
On Feb 17, 12:18 pm, 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
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
More information about the Python-list
mailing list