Created
October 29, 2015 16:12
-
-
Save fdgogogo/b04340b649b055243a5c to your computer and use it in GitHub Desktop.
Flatten dict and vice versa
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" 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