Project

General

Profile

1 1876 aaronmk
# Dictionaries
2
3 1885 aaronmk
import itertools
4 1876 aaronmk
5 1907 aaronmk
import util
6
7 2649 aaronmk
def is_dict(value): return hasattr(value, '__getitem__')
8
9 1885 aaronmk
class IdDict(dict):
10
    '''A dict that stores objects by id()'''
11
12
    def add(self, *values):
13
        for value in values: self[id(value)] = value
14
        return self
15
16
    def add_vars(self, vars_): return self.add(*vars_.values())
17
18 1876 aaronmk
class MergeDict:
19
    '''A dict that checks each of several dicts'''
20 1885 aaronmk
21 1876 aaronmk
    def __init__(self, *dicts): self.dicts = dicts
22
23
    def __getitem__(self, key):
24
        for dict_ in self.dicts:
25
            try: return dict_[key]
26
            except KeyError: pass
27
        raise # reraise last KeyError
28 1907 aaronmk
29 1911 aaronmk
30
class AttrsDictView:
31
    '''A dict view of an object's attributes
32
    @pre If you want __iter__() to work, value must have a __dict__
33
    '''
34
35
    def __init__(self, value): self.value = value
36
37
    def __iter__(self): return iter(self.value.__dict__)
38
39
    def __getitem__(self, key): return getattr(self.value, key)
40
41 1907 aaronmk
def make_hashable(value):
42
    if isinstance(value, list): value = tuple(value)
43
    elif isinstance(value, dict): value = util.NamedTuple(**value)
44
    return value
45 2384 aaronmk
46
def join(dict0, dict1):
47
    '''Joins dict0 (A->B mapping) to dict1 (B->C mapping) SQL-style.
48
    If a value in dict0 has no key in dict1, uses the value itself.
49
    '''
50
    new_dict = {}
51
    for out, in_ in dict0.iteritems():
52
        new_dict[out] = dict1.get(in_, in_) # use in_ if no match found
53
    return new_dict