Created
September 26, 2019 13:25
-
-
Save wellic/aad14be76369b8b02c96167b3a5c7448 to your computer and use it in GitHub Desktop.
Nested dict <-> path (flatten dict)
This file contains hidden or 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
import json | |
SEPARATOR = '/' | |
def encode_value(value): | |
return json.dumps(value, indent=2, sort_keys=True) | |
def decode_value(item_value): | |
if hasattr(item_value, 'decode'): | |
item_value = item_value.decode() | |
try: | |
result = json.loads(item_value) | |
except: | |
result = item_value | |
return result | |
def decode_key(path, item_key, separator): | |
return (item_key[len(path):] if item_key.startswith(path) else item_key).split(separator) | |
def dict_to_flatten_list(data, key='', separator=SEPARATOR, prefix=''): | |
def _process(data, key='', separator=SEPARATOR, prefix=''): | |
return {separator.join(filter(None, [key, prefix, k1 if prefix else k1])): v1 # NOSONAR | |
for k2, v2 in data.items() | |
for k1, v1 in _process(key='', data=v2, separator=separator, prefix=k2).items() | |
} if isinstance(data, dict) else { | |
separator.join(filter(None, [key, prefix])): encode_value(data)} | |
if key: | |
return _process(data=data, key=key, separator=separator) | |
return {'': encode_value(data)} | |
def flatten_list_to_dict(data, key='', separator=SEPARATOR): | |
def _insert(dct, lst): | |
for x in lst[:-2]: | |
dct[x] = dct = dct.get(x, {}) | |
dct.update({lst[-2]: lst[-1]}) | |
if not data: | |
return None | |
if isinstance(data, (list, set, tuple)): | |
lsts = list([*(decode_key(key, item['Key'], separator)), decode_value(item['Value'])] for item in data) | |
result = {} | |
for lst in lsts: | |
keys = list(filter(None, lst[:-1])) | |
if not keys: | |
return lst[-1] | |
_insert(result, [*keys, lst[-1]]) | |
return result | |
if data and isinstance(data, dict): | |
if '' in data: | |
return decode_value(data['']) | |
else: | |
flatten_list = [{'Key': k, "Value": v} for k, v in data.items()] | |
return flatten_list_to_dict(flatten_list, key=key, separator=separator) | |
if isinstance(data, str): | |
return json.loads(data) | |
return data | |
def pop_param_from_dict(args, key, default_value=None): | |
return args.pop(key, default_value) if isinstance(args, dict) else default_value | |
def prepare_full_path_name(keys=None, separator=SEPARATOR): | |
try: | |
if isinstance(keys, (str, int, float,)): | |
path = keys.strip(separator) | |
elif isinstance(keys, (dict, set, list, tuple)): | |
path = separator.join(key.strip(separator) for key in filter(None, keys)) | |
else: | |
raise Exception('Unallowed type') | |
return path.strip() | |
except: | |
return None |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment