-
-
Notifications
You must be signed in to change notification settings - Fork 48
/
keylist_util.py
82 lines (65 loc) · 1.96 KB
/
keylist_util.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# -*- coding: utf-8 -*-
from benedict.utils import type_util
def _get_index(key):
if type_util.is_integer(key):
return key
return None
def _get_item_key_and_value(item, key):
if type_util.is_list(item):
index = _get_index(key)
if index is not None:
return (index, item[index], )
elif type_util.is_dict(item):
return (key, item[key], )
raise KeyError('Invalid key: "{}"'.format(key))
def _get_or_new_item_value(item, key, subkey):
try:
_, value = _get_item_key_and_value(item, key)
if not type_util.is_dict_or_list(value):
raise TypeError
except (IndexError, KeyError, TypeError, ):
value = _new_item_value(subkey)
item[key] = value
return value
def _new_item_value(key):
index = _get_index(key)
return {} if index is None else []
def _set_item_value(item, key, value):
index = _get_index(key)
if index is not None:
try:
# overwrite existing index
item[index] = value
except IndexError:
# insert index
item += ([None] * (index - len(item)))
item.insert(index, value)
else:
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
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
j = len(keys)
while i < j:
key = keys[i]
if i < (j - 1):
item = _get_or_new_item_value(item, key, keys[i + 1])
i += 1
continue
_set_item_value(item, key, value)
break