Case insensitive dictionary?

Jason Mobarak jason at __no_spam__mobarak.name
Sun Jun 27 01:38:34 CEST 2004


Elbert Lev wrote:
> Thanks!
> 
> In my case I know for sure, that keys are strings. So I fill the
> dictionary with keys as they come to me from the source (preserve the
> case). Once the dictionary is filled, it is a "READ ONLY" object. In
> other words: there is no group operation writing it back to the source
> and there is no reason to modify it.
> 
> Is there something wrong with this code:
> 
> class RegValuesDict(dict):
>     def __init__(self):
>         pass    
>     def __getitem__(self, k):
>         try:
>             tmpk = k.strip().lower()
>             for key in self.keys():
>                 if key.strip().lower() == tmpk:
>                     return dict.__getitem__(self, key)
>         except:
>             pass
>         return None
>     def has_key(self, k):
>         try:
>             tmpk = k.strip().lower()
>             for key in self.keys():
>                 if key.strip().lower() == tmpk:
>                     return True
>         except:
>             pass
>         return False
> ########
> 
> regdict = RegValuesDict()
> regdict["keyname1"] = "value1"
> regdict["keyname2"] = "value1"
> 
> val1 = regdict["keyName1"]
> if val1 == None:
>     print "Too bad"
> 
> or
> 
> if not regdict.has_key("keyName1"):
>     print "Too bad"
> else:
>     val1 = regdict["keyName1"]
> 
> or
> 
> val1 = regdict.get("keyName1", "good value")
> 
> Doing this in such a way, I remove the need for trapping exceptions in
> every line of the client code.
> 
> Again: is there something wrong with this approach?

"""
What's wrong with putting the keys in lowercase? The only thing I can 
see that's wrong is that your dictionary isn't really a dictionary 
anymore, in the sense that you don't have O(1) retreival of items -- I'm 
not sure if that's the case with python dictionaries -- but still... if 
you need to somehow get back the original value you could do something 
like...
"""

import UserDict

class CaseInsentiveDictDeux (dict, UserDict.DictMixin):

     def __init__ (self, *args, **kw):

         self.orig = {}
         super (CaseInsentiveDictDeux, self).__init__(*args, **kw)

     def items (self):

         keys = dict.keys(self)
         values = dict.values(self)
         return [(self.orig[k],v) for k in keys for v in values]

     def __setitem__ (self, k, v):

         hash_val = hash(k.lower()) # Hash value of strings is normalized
         self.orig[hash_val] = k
         dict.__setitem__(self, hash_val, v)

     def __getitem__ (self, k):

         return dict.__getitem__(self, hash(k.lower()))

     def __contains__ (self, k):

         return dict.__contains__(self, hash(k.lower()))


d = CaseInsentiveDictDeux()

d['Foo'] = 'Bar'

print d['foo']
print 'foO' in d
print d.items()

"""Where you are trading time for space"""



More information about the Python-list mailing list