diff --git a/benedict/dicts/keylist/keylist_util.py b/benedict/dicts/keylist/keylist_util.py index 0bfbec9..5a872fb 100644 --- a/benedict/dicts/keylist/keylist_util.py +++ b/benedict/dicts/keylist/keylist_util.py @@ -9,46 +9,33 @@ def _get_index(key): return None -def _get_item_value(item, key): +def _get_item_key_and_value(item, key): if type_util.is_list(item): index = _get_index(key) if index is not None: - return item[index] + return (index, item[index], ) elif type_util.is_dict(item): - return item[key] + return (key, item[key], ) raise KeyError +def _get_or_new_item_value(item, key, subkey): + try: + item_key, item_value = _get_item_key_and_value(item, key) + if not type_util.is_dict_or_list(item_value): + raise TypeError + except (IndexError, KeyError, TypeError, ): + item_value = _new_item_value(subkey) + item[key] = item_value + return item_value + + def _new_item_value(key): index = _get_index(key) return {} if index is None else [] -def get_item(d, keys): - items = get_items(d, keys) - return items[-1] if items else (None, None, None, ) - - -def get_items(d, keys): - items = [] - item = d - value = None - for key in keys: - try: - value = _get_item_value(item, key) - if type_util.is_list(item): - index = _get_index(key) - items.append((item, index, value, )) - else: - items.append((item, key, value, )) - item = value - except (IndexError, KeyError, ): - items.append((None, None, None, )) - break - return items - - -def set_item_value(item, key, value): +def _set_item_value(item, key, value): index = _get_index(key) if index is not None: try: @@ -62,6 +49,26 @@ def set_item_value(item, key, value): item[key] = value +def get_item(d, keys): + items = get_items(d, keys) + return items[-1] if items else (None, None, None, ) + + +def get_items(d, keys): + items = [] + item = d + value = None + for key in keys: + try: + item_key, item_value = _get_item_key_and_value(item, key) + items.append((item, item_key, item_value, )) + item = item_value + except (IndexError, KeyError, ): + items.append((None, None, None, )) + break + return items + + def set_item(d, keys, value): item = d i = 0 @@ -69,16 +76,8 @@ def set_item(d, keys, value): while i < j: key = keys[i] if i < (j - 1): - try: - subitem = _get_item_value(item, key) - if not type_util.is_dict_or_list(subitem): - raise TypeError - except (IndexError, KeyError, TypeError, ): - subkey = keys[i + 1] - subitem = item[key] = _new_item_value(subkey) - item = subitem + item = _get_or_new_item_value(item, key, keys[i + 1]) i += 1 continue - set_item_value(item, key, value) + _set_item_value(item, key, value) break -