Case insensitive dictionary?
Jason Mobarak
jason at __no_spam__mobarak.name
Sat Jun 26 19:38:34 EDT 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