473,411 Members | 1,991 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,411 software developers and data experts.

Case insensitive dictionary?

Hi!

Here is the problem:

I have a dictionary. Keys are strings. How to make dictionary lookup
case insensitive?

In other words:
If dict = {'First":"Bob", "Last":"Tom"}, dict["first"] should return
"Bob"

Maybe dictionary is not the right data type? If so what is?
Jul 18 '05 #1
6 12418

insert and access your keys with :

mydict[ mykey.lower() ] = value

you can also create a subclass of dict to do this for you.
On 25 Jun 2004 10:21:21 -0700, Elbert Lev <el*******@hotmail.com> wrote:
Hi!

Here is the problem:

I have a dictionary. Keys are strings. How to make dictionary lookup
case insensitive?

In other words:
If dict = {'First":"Bob", "Last":"Tom"}, dict["first"] should return
"Bob"

Maybe dictionary is not the right data type? If so what is?


--
Using Opera's revolutionary e-mail client: http://www.opera.com/m2/
Jul 18 '05 #2

Be careful about what character encoding and locale you use, as lower()
won't process accented characters correctly if the encoding is wrong.
On 25 Jun 2004 10:21:21 -0700, Elbert Lev <el*******@hotmail.com> wrote:
Hi!

Here is the problem:

I have a dictionary. Keys are strings. How to make dictionary lookup
case insensitive?

In other words:
If dict = {'First":"Bob", "Last":"Tom"}, dict["first"] should return
"Bob"

Maybe dictionary is not the right data type? If so what is?


--
Using Opera's revolutionary e-mail client: http://www.opera.com/m2/
Jul 18 '05 #3
Elbert Lev wrote:
Hi!

Here is the problem:

I have a dictionary. Keys are strings. How to make dictionary lookup
case insensitive?

In other words:
If dict = {'First":"Bob", "Last":"Tom"}, dict["first"] should return
"Bob"

Maybe dictionary is not the right data type? If so what is?


"""
More or less complete, you might want to add some more tests...
"""

import UserDict
import sys
import traceback

class CaseInsensitiveDict (dict, UserDict.UserDict, UserDict.DictMixin):

def __init__ (self, init=None, **kw):

if init is not None:
return super(CaseInsensitiveDict,
self).__init__(self.lowerDict(init), **kw)

return super(CaseInsensitiveDict, self).__init__(**kw)

def ifStrKey (cls, key):

if hasattr(key, 'lower'):
return key.lower()

return key

ifStrKey = classmethod(ifStrKey)

def lowerDict (cls, d):

# this handle's the case were d is a "mapping type"
# like (('foo','oof'), ('baz', 'zab'))
d = dict(d)
return dict([(k.lower(), v.lower()) for k in d.keys() for v in
d.values()])

lowerDict = classmethod(lowerDict)

def __contains__ (self, key):
return super(CaseInsensitiveDict,
self).__contains__(self.ifStrKey(key))

def get (self, key, default=None):
return super(CaseInsensitiveDict, self).get(self.ifStrKey(key),
default=default)

def pop (self, key, *args):
return super(CaseInsensitiveDict, self).pop(self.ifStrKey(key),
*args)

def setdefault (self, key, default):
return super(CaseInsensitiveDict, self).pop(self.ifStrKey(key),
default)

def __delitem__ (self, key):
return super(CaseInsensitiveDict,
self).__delitem__(self.ifStrKey(key))

def __getitem__ (self, key):
return super(CaseInsensitiveDict,
self).__getitem__(self.ifStrKey(key))

def __setitem__ (self, key, item):
return super(CaseInsensitiveDict,
self).__setitem__(self.ifStrKey(key), item)

def has_key (self, key):
return super(CaseInsensitiveDict,
self).has_key(self.ifStrKey(key))

def update (self, d):
return super(CaseInsensitiveDict, self).update(self.lowerDict(d))

def print_tb (e):

e_fmt = traceback.format_exception(e.__class__, e, sys.exc_traceback)
sys.stderr.write(''.join(e_fmt))
print

def test_d (d, k):

print `d`
print 'Key', `k`

try:
val = `d[k]`
print 'Value', val

except KeyError, e:

print 'Key failed'
print_tb(e)

print

if __name__ == '__main__':

td = {'FOO':'bar'}
d = CaseInsensitiveDict(td)
test_d(d, 'FOO')

d = CaseInsensitiveDict()
d.update(td)
test_d(d, 'FOO')

try:
# this should fail
d = CaseInsensitiveDict((('foo', 'oof',), ('zab',)))
except Exception, e:
print_tb(e)

d = CaseInsensitiveDict((('foo', 'oof',), ('zab', 'baz',)))
test_d(d, 'FOO')
d[object()] = 'bar'
print `d`
Jul 18 '05 #4
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?
Jul 18 '05 #5
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"""
Jul 18 '05 #6
el*******@hotmail.com (Elbert Lev) wrote in message news:<94**************************@posting.google. com>...
Hi!

Here is the problem:

I have a dictionary. Keys are strings. How to make dictionary lookup
case insensitive?

In other words:
If dict = {'First":"Bob", "Last":"Tom"}, dict["first"] should return
"Bob"

Maybe dictionary is not the right data type? If so what is?


I'm probably a bit late on this one... but I've written a complete
case-insensitive dictionary (and list..) with all dictionary methods
implemented....

It's called caseless and available at :
http://www.voidspace.org.uk/atlantib...html#configobj

I've tested it fairly well as it the base class for my configuration
module ConfigObj.

Regards,

Fuzzy

http://www.voidspace.org.uk/atlantib...thonutils.html
Jul 18 '05 #7

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
by: noah | last post by:
Can anyone think of a way to make array keys case insensitive? An option on any recent PHP would be to convert all array keys to lowercase using the standard array_change_key_case() function. As...
11
by: Ville Vainio | last post by:
I need a dict (well, it would be optimal anyway) class that stores the keys as strings without coercing the case to upper or lower, but still provides fast lookup (i.e. uses hash table). >> d...
2
by: Tumurbaatar S. | last post by:
I need something like Scripting.Dictionary but with case insensitive keys, i.e. dict.Item("mykey") and dict.Item("MyKeY") should be identical. Any ideas?
0
by: William Stacey [MVP] | last post by:
Trying to figure out Dictionary<> and using CaseInsensitive Comparer<> like I did with normal Hashtable. The Hashtable can take a case insenstive Comparer and a Case insensitive HashCode provider....
5
by: Mark Rae | last post by:
Hi, In v1.x, I used to use the following code to create a case-insensitive Hashtable: Hashtable MyHashtable = new Hashtable(CaseInsensitiveHashCodeProvider.Default,...
4
by: Mark Rae | last post by:
Hi, Is it possible to create a case-insensitive List<stringcollection? E.g. List<stringMyList = new List<string>; MyList.Add("MyString"); So that:
7
by: John Henry | last post by:
I believe the standard dictionary should be amened to allow the use of case insensitive keys - as an option. I found some work done by others to do that at: ...
2
by: pamela fluente | last post by:
Hi I am doing something like: Dim MiDict As New System.Collections.Generic.Dictionary(Of String, MyObject) how should I change the above so that the string comparison (key) is done using...
0
by: J. Cliff Dyer | last post by:
Please keep the discussion on-list. On Fri, 2008-09-05 at 15:36 +0200, Maric Michaud wrote: That does not get the same behavior as the OP's original solution. The OP's solution retrieves the...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.