-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbasic_types.py
134 lines (105 loc) · 3.63 KB
/
basic_types.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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
import random
import re
from functools import reduce
import collections
import numpy as np
from blox import AttrDict
def dict_concat(d1, d2):
if not set(d1.keys()) == set(d2.keys()):
raise ValueError("Dict keys are not equal. got {} vs {}.".format(d1.keys(), d2.keys()))
for key in d1:
d1[key] = np.concatenate((d1[key], d2[key]))
def map_dict(fn, d):
"""takes a dictionary and applies the function to every element"""
return type(d)(map(lambda kv: (kv[0], fn(kv[1])), d.items()))
def filter_dict(fn, d):
"""takes a dictionary and applies the function to every element"""
return type(d)(filter(fn, d.items()))
def listdict2dictlist(LD):
""" Converts a list of dicts to a dict of lists """
# Take intersection of keys
keys = reduce(lambda x,y: x & y, (map(lambda d: d.keys(), LD)))
# Note dict.__getitem__ is necessary for subclasses of dict that override getitem
return type(LD[0])({k: [dict.__getitem__(d, k) for d in LD] for k in keys})
def dictlist2listdict(DL):
" Converts a dict of lists to a list of dicts "
return [dict(zip(DL,t)) for t in zip(*DL.values())]
def subdict(dict, keys, strict=True):
if not strict:
keys = dict.keys() & keys
return AttrDict((k, dict[k]) for k in keys)
def maybe_retrieve(d, key):
if hasattr(d, key):
return d[key]
else:
return None
def str2int(str):
try:
return int(str)
except ValueError:
return None
def float_regex():
numeric_const_pattern = '[-+]? (?: (?: \d* \. \d+ ) | (?: \d+ \.? ) )(?: [Ee] [+-]? \d+ ) ?'
rx = re.compile(numeric_const_pattern, re.VERBOSE)
return rx
def rand_split_list(list, frac=0.5, seed=None):
rng = random.Random()
if seed is not None: rng.seed(seed)
rng.shuffle(list)
split = int(frac * len(list))
return list[:split], list[split:]
def dot2nesteddict(dot_map_dict):
"""
Convert something like
```
{
'one.two.three.four': 4,
'one.six.seven.eight': None,
'five.nine.ten': 10,
'five.zero': 'foo',
}
```
into its corresponding nested dict.
Taken from rlkit by Vitchyr Pong
http://stackoverflow.com/questions/16547643/convert-a-list-of-delimited-strings-to-a-tree-nested-dict-using-python
:param dot_map_dict:
:return:
"""
tree = {}
for key, item in dot_map_dict.items():
split_keys = key.split('.')
if len(split_keys) == 1:
if key in tree:
raise ValueError("Duplicate key: {}".format(key))
tree[key] = item
else:
t = tree
for sub_key in split_keys[:-1]:
t = t.setdefault(sub_key, {})
last_key = split_keys[-1]
if not isinstance(t, dict):
raise TypeError(
"Key inside dot map must point to dictionary: {}".format(
key
)
)
if last_key in t:
raise ValueError("Duplicate key: {}".format(last_key))
t[last_key] = item
return tree
def nested2dotdict(d, parent_key=''):
"""
Convert a recursive dictionary into a flat, dot-map dictionary.
Taken from rlkit by Vitchyr Pong
:param d: e.g. {'a': {'b': 2, 'c': 3}}
:param parent_key: Used for recursion
:return: e.g. {'a.b': 2, 'a.c': 3}
"""
items = []
for k, v in d.items():
new_key = parent_key + "." + k if parent_key else k
if isinstance(v, collections.MutableMapping):
items.extend(nested2dotdict(v, new_key).items())
else:
items.append((new_key, v))
return dict(items)