flattening a dict

B

Benjamin

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.

Why don't you do your homework on your own for a change ? Or at least
pretend you're even trying ?
<excuseme>
Here's a attempt:
def dictflatten(d, prefix=None, depth=2, cur_depth=0):
result = {}
if prefix is None: prefix = tuple()
if isinstance(prefix, basestring): prefix = (prefix,)
cur_depth += 1
for k, v in d.iteritems():
key = prefix + (k,)
print key, cur_depth
if isinstance(v, dict):
if v:
if cur_depth >= depth:
result.update(dictflatten(v, key, depth,
cur_depth))
else:
result.update(dictflatten(v, k, depth, cur_depth))
else:
result[key] = None
else:
result[k] = v
return result
</excuseme>
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,774
Messages
2,569,599
Members
45,170
Latest member
Andrew1609
Top