Created
April 18, 2020 13:17
-
-
Save wellic/577674a4431b4a8fa56c2134bb80106a to your computer and use it in GitHub Desktop.
work with nested dicts
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 collections | |
| import os | |
| import re | |
| from copy import deepcopy | |
| from functools import reduce | |
| from operator import getitem | |
| def update_nested_dicts(base_dct, new_dct, only_existed_keys=False): | |
| # IN[]: | |
| # f1 = {'1': {'a': 'f1_1a', 'b': 'f1_1b', 'd': 'f1_1c'}, '2': 'f1_2', '3': 'f1_3'} | |
| # f2 = {'1': {'a': 'f2_1a', 'b': 'f2_1b', 'c': 'f2_1c'}, '2': 'f2_2', '4': 'f2_4'} | |
| # c1 = update_nested_dicts(f1, f2) | |
| # c2 = update_nested_dicts(f1, f2, None) | |
| # c3 = update_nested_dicts(f1, f2, False) | |
| # c4 = update_nested_dicts(f1, f2, True) | |
| # print(f"c1={c1}\nc4={c4}\n{c1 == c2, c2 == c3, c3 != c4}") | |
| # | |
| # Out[]: | |
| # c1={'1': {'a': 'f2_1a', 'b': 'f2_1b', 'd': 'f1_1c', 'c': 'f2_1c'}, '2': 'f2_2', '3': 'f1_3', '4': 'f2_4'} | |
| # c4={'1': {'a': 'f2_1a', 'b': 'f2_1b', 'd': 'f1_1c'}, '2': 'f2_2', '3': 'f1_3'} | |
| # (True, True, True) | |
| if base_dct is None: | |
| base_dct = {} | |
| if not (new_dct and isinstance(new_dct, dict)): | |
| return deepcopy(base_dct) | |
| if not (base_dct and isinstance(base_dct, dict)): | |
| return deepcopy(new_dct) | |
| rtn_dct = deepcopy(base_dct) | |
| if only_existed_keys is True: | |
| new_dct = {key: new_dct[key] for key in set(rtn_dct).intersection(set(new_dct))} | |
| rtn_dct.update({ | |
| key: update_nested_dicts(rtn_dct[key], new_dct[key], only_existed_keys=only_existed_keys) | |
| if isinstance(rtn_dct.get(key), dict) and isinstance(new_dct[key], dict) | |
| else deepcopy(new_dct[key]) | |
| for key in new_dct.keys() | |
| }) | |
| return rtn_dct | |
| def get_nested_item(data, keys): | |
| try: | |
| return reduce(getitem, filter(None, keys), data) | |
| except: | |
| return None | |
| def set_nested_item(data, keys, value): | |
| try: | |
| for key in keys[:-1]: | |
| data = data.setdefault(key, {}) | |
| data[keys[-1]] = deepcopy(value) | |
| finally: | |
| return data |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment