1   
 2   
 3   
 4   
 5   
 6   
 7   
 8   
 9   
10   
11   
12   
13   
14   
15   
16  try: 
17      from collections import defaultdict 
18      assert defaultdict 
19  except ImportError: 
20       
22 -        def __init__(self, default_factory=None, *args, **kwargs): 
 23              self._default_factory = default_factory 
24              dict.__init__(self, *args, **kwargs) 
 26              if key not in self and self._default_factory: 
27                  self[key] = self._default_factory() 
28              return dict.__getitem__(self, key) 
  29   
31      """ 
32      This is a collection of named sets.  In principal, it contains an empty set 
33      for every name, and you can add things to sets, discard things from sets, 
34      and so on. 
35   
36      >>> ks = KeyedSets() 
37      >>> ks['tim']                   # get a named set 
38      set([]) 
39      >>> ks.add('tim', 'friendly')   # add an element to a set 
40      >>> ks.add('tim', 'dexterous') 
41      >>> ks['tim'] 
42      set(['friendly', 'dexterous']) 
43      >>> 'tim' in ks                 # membership testing 
44      True 
45      >>> 'ron' in ks 
46      False 
47      >>> ks.discard('tim', 'friendly')# discard set element 
48      >>> ks.pop('tim')               # return set and reset to empty 
49      set(['dexterous']) 
50      >>> ks['tim'] 
51      set([]) 
52   
53      This class is careful to conserve memory space - empty sets do not occupy 
54      any space. 
55      """ 
58 -    def add(self, key, value): 
 59          if key not in self.d: 
60              self.d[key] = set() 
61          self.d[key].add(value) 
 63          if key in self.d: 
64              self.d[key].discard(value) 
65              if not self.d[key]: 
66                  del self.d[key] 
 70          return self.d.get(key, set()) 
 72          if key in self.d: 
73              return self.d.pop(key) 
74          return set() 
  75