def unflatten_list(flat_dict, separator='<STR_LIT:_>'):
_unflatten_asserts(flat_dict, separator)<EOL>unflattened_dict = unflatten(flat_dict, separator)<EOL>def _convert_dict_to_list(object_, parent_object, parent_object_key):<EOL><INDENT>if isinstance(object_, dict):<EOL><INDENT>for key in object_:<EOL><INDENT>if isinstance(object_[key], dict):<EOL><INDENT>_convert_dict_to_list(object_[key], object_, key)<EOL><DEDENT><DEDENT>try:<EOL><INDENT>keys = [int(key) for key in object_]<EOL>keys.sort()<EOL><DEDENT>except (ValueError, TypeError):<EOL><INDENT>keys = []<EOL><DEDENT>keys_len = len(keys)<EOL>if (keys_len > <NUM_LIT:0> and sum(keys) ==<EOL>int(((keys_len - <NUM_LIT:1>) * keys_len) / <NUM_LIT:2>) and keys[<NUM_LIT:0>] == <NUM_LIT:0> and<EOL>keys[-<NUM_LIT:1>] == keys_len - <NUM_LIT:1> and<EOL>check_if_numbers_are_consecutive(keys)):<EOL><INDENT>parent_object[parent_object_key] = []<EOL>for key_index, key in enumerate(keys):<EOL><INDENT>parent_object[parent_object_key].append(object_[str(key)])<EOL>_convert_dict_to_list(parent_object[parent_object_key][-<NUM_LIT:1>],<EOL>parent_object[parent_object_key],<EOL>key_index)<EOL><DEDENT><DEDENT><DEDENT><DEDENT>_convert_dict_to_list(unflattened_dict, None, None)<EOL>return unflattened_dict<EOL>
Unflattens a dictionary, first assuming no lists exist and then tries to
identify lists and replaces them
This is probably not very efficient and has not been tested extensively
Feel free to add test cases or rewrite the logic
Issues that stand out to me:
- Sorting all the keys in the dictionary, which specially for the root
dictionary can be a lot of keys
- Checking that numbers are consecutive is O(N) in number of keys

:param flat_dict: dictionary with no hierarchy
:param separator: a string that separates keys
:return: a dictionary with hierarchy