Skip to content

Instantly share code, notes, and snippets.

@fdgogogo
Created October 29, 2015 16:12
Show Gist options
  • Save fdgogogo/b04340b649b055243a5c to your computer and use it in GitHub Desktop.
Save fdgogogo/b04340b649b055243a5c to your computer and use it in GitHub Desktop.
Flatten dict and vice versa
""" Flatten dict and vice versa
Authored by: Fang Jiaan ([email protected])
Example:
>>> example = {'a': 1, 'b': {}, 'c': {'d': [], 'e': {'f': 0, 'h': u'xxx', 'i': {'j'}, 'k': object()}}}
>>> flatten_dict(example) # doctest: +ELLIPSIS
{'a': 1, 'b': {}, 'c.d': [], 'c.e.k': <object object at ...>, 'c.e.i': set(['j']), 'c.e.h': u'xxx', 'c.e.f': 0}
>>> assert nestify_dict(flatten_dict(example)) == example
>>> assert 'c.e.h' in flatten_dict(example)
>>> assert flatten_dict(example)['c.e.h'] == example['c']['e']['h']
>>> example2 = {'x.y': 1}
>>> flatten_dict(example2) # doctest: +IGNORE_EXCEPTION_DETAIL
Traceback (most recent call last):
ValueError: Separator . already in key, this may lead unexpected behaviour, choose another.
"""
import collections
def flatten_dict(d, parent_key='', sep='.', quiet=False):
items = []
for k, v in d.items():
if not quiet and sep in k:
raise ValueError('Separator "%(sep)s" already in key, '
'this may lead unexpected behaviour, '
'choose another.' % dict(sep=sep))
new_key = parent_key + sep + k if parent_key else k
if isinstance(v, collections.MutableMapping):
items.extend(flatten_dict(v, new_key, sep=sep).items())
if not v: # empty dict
items.append((new_key, v))
else:
items.append((new_key, v))
return dict(items)
def nestify_dict(d, sep='.'):
ret = {}
for k, v in d.items():
if sep in k:
keys = k.split(sep)
target = ret
while len(keys) > 1:
current_key = keys.pop(0)
target = target.setdefault(current_key, {})
else:
assert len(keys) == 1
target[keys[0]] = v
else:
ret[k] = v
return ret
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment