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
|
from collections import namedtuple
def from_keyed_iterable(iterable, key, filter_func=None):
"""Construct a dictionary out of an iterable, using an attribute name as
the key. Optionally provide a filter function, to determine what should be
kept in the dictionary."""
generated = {}
for element in iterable:
try:
k = getattr(element, key)
except AttributeError:
raise RuntimeError("{} does not have the keyed attribute: {}".format(
element, key
))
if filter_func is None or filter_func(element):
if k in generated:
generated[k] += [element]
else:
generated[k] = [element]
return generated
def subtract_by_key(dict_a, dict_b):
"""given two dicts, a and b, this function returns c = a - b, where
a - b is defined as the key difference between a and b.
e.g.,
{1:None, 2:3, 3:"yellow", 4:True} - {2:4, 1:"green"} =
{3:"yellow", 4:True}
"""
difference_dict = {}
for key in dict_a:
if key not in dict_b:
difference_dict[key] = dict_a[key]
return difference_dict
def subtract(dict_a, dict_b, strict=False):
"""a stricter form of subtract_by_key(), this version will only remove an
entry from dict_a if the key is in dict_b *and* the value at that key
matches"""
if not strict:
return subtract_by_key(dict_a, dict_b)
difference_dict = {}
for key in dict_a:
if key not in dict_b or dict_b[key] != dict_a[key]:
difference_dict[key] = dict_a[key]
return difference_dict
WinnowedResult = namedtuple("WinnowedResult", ['has', 'has_not'])
def winnow_by_keys(dct, keys=None, filter_func=None):
"""separates a dict into has-keys and not-has-keys pairs, using either
a list of keys or a filtering function."""
has = {}
has_not = {}
for key in dct:
key_passes_check = False
if keys is not None:
key_passes_check = key in keys
elif filter_func is not None:
key_passes_check = filter_func(key)
if key_passes_check:
has[key] = dct[key]
else:
has_not[key] = dct[key]
return WinnowedResult(has, has_not)
def intersection(dict_a, dict_b, strict=True):
intersection_dict = {}
for key in dict_a:
if key in dict_b:
if not strict or dict_a[key] == dict_b[key]:
intersection_dict[key] = dict_a[key]
return intersection_dict
def setdefaults(dct, defaults):
"""Given a target dct and a dict of {key:default value} pairs,
calls setdefault for all of those pairs."""
for key in defaults:
dct.setdefault(key, defaults[key])
return dct
|