CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_7/src/CondCore/TagCollection/python/multivaluedict.py

Go to the documentation of this file.
00001 #  Sequential Dictionary Class                                                 #
00002 '''
00003 msedict - multiple value dictionary, keeps multiple values per key
00004 You can slice, add, sort with dictionaries. The functional operations map, filter, reduce can also be used .
00005 The dictionary can also be used like a stack with push and pop. It can be used to Split , reverse and swap keys and values.
00006 '''
00007 
00008 from seqvaluedict import seqdict   #Sequential Single Value Dictionary
00009 from UserList import UserList
00010 
00011 class MyUserList(UserList):
00012     from UserList import UserList
00013     def __init__(self,parent,liste=None):
00014       UserList.__init__(self,liste)
00015       self.parent = parent  #remember parent for call-back
00016     def __delitem__(self, i):
00017       del self.data[i]
00018       if self.data==[]:     #call-back, deletes item of parent
00019         index = self.parent.values().index([])
00020         del self.parent[index:index+1]
00021         
00022 class mseqdict(seqdict):    #Sequential Multiple Value Dictionary
00023   def __init__(self,List=[],Dict={}):
00024     self.list = []
00025     self.dict = {}
00026     if not List:
00027       pass     
00028     elif type(List)==type({}):
00029       for key,value in List.items():
00030         self.__setitem__(key,value)
00031     elif List and not Dict: #dict.items()
00032       for key,value in List:
00033         if isinstance(value,MyUserList):
00034           for v in value:
00035             self.__setitem__(key,v)
00036         else:
00037           self.__setitem__(key,value)     
00038     elif type(List)==type(Dict)==type([]):
00039       for key,value in map(None,List,Dict):
00040         self.__setitem__(key,value)
00041     else:
00042       if isinstance(Dict.values()[0],MyUserList):
00043         self.dict = Dict
00044         self.list = List
00045       else:
00046         for key in List:
00047           value = Dict[key]
00048           if type(value)==type([]):
00049             for v in value:
00050               self.__setitem__(key,v)
00051           else:
00052             self.__setitem__(key,value)     
00053   def __setitem__(self,key,value):
00054     if not self.dict.has_key(key):
00055       self.list.append(key)
00056       if isinstance(value,MyUserList):
00057         self.dict[key] = value
00058       else:
00059         self.dict[key]=MyUserList(self,[value])
00060     else:
00061       values = self.dict[key]
00062       if isinstance(value,MyUserList):
00063         for v in value:
00064           if not v in values:
00065             values.extend(MyUserList(self,[v]))
00066       else:
00067         if not value in values:
00068           values.extend(MyUserList(self,[value]))
00069   def __delitem__(self, key):
00070     del self.dict[key]
00071     self.list.remove(key)      
00072 
00073   def append(self,key,value):
00074     self.__setitem__(key,value)                 
00075   def __setslice__(self,start,stop,newdict):
00076     start = max(start,0); stop = max(stop,0)
00077     delindexes = []
00078     for key in newdict.keys():
00079       if self.dict.has_key(key):
00080         index = self.list.index(key)
00081         delindexes.append(index)
00082         if index < start:
00083           start = start - 1
00084           stop  = stop  - 1
00085         elif index >= stop:
00086           pass
00087         else:
00088           stop  = stop - 1
00089       else:
00090         self.dict[key]=UserList(self)
00091     delindexes.sort()
00092     delindexes.reverse()
00093     for index in delindexes:
00094       key = self.list[index]
00095       #del   self.dict[key]
00096       del  self.list[index]
00097     self.list[start:stop] = newdict.list[:]
00098     self.update(newdict.dict)  
00099   def copy(self):
00100     values = map(lambda x:x[:],self.values())
00101     return self.__class__(self.list,values)
00102   def count(self,value):
00103     vallist = self.dict.values()
00104     return map(lambda x,y=value:x.count(y),vallist).count(1)
00105   def filter(self,function,filtervalues=0):
00106     if   filtervalues == 1: #consider key and all keyvalues at once
00107       dict = self.__class__()
00108       for key,values in self.items():
00109         if function(key,values):
00110           dict[key]=values
00111       return dict
00112     elif filtervalues == 2: #consider key and every keyvalue for itself
00113       dict = self.__class__()
00114       for key,values in self.items():
00115         for value in values:
00116           if function(key,value):
00117             dict[key]=value
00118       return dict
00119     else:                   #consider key only
00120       liste=filter(function,self.list)
00121       dict = {}
00122       for i in liste:
00123         dict[i]=self.dict[i]
00124       return self.__class__(liste,dict)
00125   def map(self,function,mapvalues=2):
00126     if   mapvalues == 1:    #consider key and all keyvalues at once
00127       dict = self.__class__()
00128       for key,values in self.items():
00129         k,v = function(key,values)
00130         dict[k]=v
00131       return dict
00132     else: #if mapvalues!=1: #consider key and every keyvalue for itself
00133       dict = self.__class__()
00134       for key,values in self.items():
00135         for value in values:
00136           k,v = function(key,value)
00137           dict[k]=v
00138       return dict
00139   def pop(self,key='...None',value='...None'):
00140     if value=='...None':
00141       if key=='...None':
00142         pos = -1
00143         key = self.list[pos]
00144       else:
00145         pos = self.list.index(key)
00146       tmp = self.dict[key]
00147       del self.dict[key]
00148       return {self.list.pop(pos):tmp}
00149     else:
00150       val = self.dict[key]
00151       index = val.index(value)
00152       tmp = val[index]
00153       del val[index]
00154       return {key:tmp}
00155   def remove(self,key,value='...None'):
00156     if value=='...None':
00157       del self[key]
00158     else:
00159       index = self[key].index(value) 
00160       del self[key][index]
00161   def sort(self,func1=None,func2=None):
00162     if not func1:
00163       self.list.sort()
00164     else:
00165       apply(self.list.sort,[func1])
00166     if func2:
00167       for value in self.values():
00168         apply(value.sort,[func2])
00169       
00170   def swap(self):
00171     tmp = self.__class__()
00172     for key,values in self.items():
00173       for value in values:
00174         tmp[value]=key
00175     self.list,self.dict = tmp.list,tmp.dict
00176     del tmp
00177   
00178   def __repr__(self):return 'mseqdict(\n%s,\n%s)'%(self.list,self.dict)
00179