Initial revision
[blender.git] / intern / python / modules / mcf / utils / dictbool.py
1 '''
2 DictBool:
3 Simplistic (and slow) implementation of Boolean operations for
4 dictionaries... really these should be implemented in C, but I
5 can't do that till I have MSVC++, which I don't really want to
6 buy... this will have to do in the meantime.
7
8 >>> from mcf.utils import dictbool
9
10 >>> a = {1:2}; b = {2:3}; c={4:5,6:7,8:9,1:5}
11
12 >>> dictbool.union(a,b,c) # overwrite a with b and the result with c
13
14 {1: 5, 2: 3, 4: 5, 8: 9, 6: 7}
15
16 >>> dictbool.collectunion(a,b,c) # collect all possible for each key
17
18 {1: [2, 5], 2: [3], 4: [5], 8: [9], 6: [7]}
19
20 >>> dictbool.intersect(a,b,c) # no common elements in all three
21
22 {}
23
24 >>> dictbool.intersect(a,c) # one element is common to both
25
26 {1: [2, 5]}
27 '''
28
29 def union(*args):
30         '''
31         Build a new dictionary with the key,val from all args,
32         first overwritten by second, overwritten by third etc. 
33         Rewritten for Python 1.5 on 98.03.31
34         '''
35         temp = {}
36         for adict in args:
37                 # following is the 1.5 version
38                 temp.update(adict)
39 #               for key,val in adict.items():
40 #                       temp[key] = val
41         return temp
42
43 def collectunion(*args):
44         '''
45         As union, save instead of overwriting, all vals are
46         returned in lists, and duplicates are appended to those
47         lists.
48         '''
49         temp = {}
50         for adict in args:
51                 for key,val in adict.items():
52                         try:
53                                 temp[key].append(val)
54                         except KeyError:
55                                 temp[key] = [val]
56         return temp
57
58 def intersect(*args):
59         '''
60         Build a new dictionary with those keys common to all args,
61         the vals of the new dict are lists of length len(args), where
62         list[ind] is the value of args[ind] for that key.
63         '''
64         args = map(lambda x: (len(x),x), args)
65         args.sort()
66         temp = {}
67         master = args[0][1]
68         rest = map(lambda x: x[1], args[1:])
69         for var,val in master.items():
70                 tempval = [val]
71                 for slave in rest:
72                         try:
73                                 tempval.append(slave[var])
74                         except KeyError:
75                                 tempval = None
76                                 break
77                 if tempval:
78                         temp[var] = tempval
79         return temp
80