Note that making a dictionary case-insensitive, by whatever mean, may well lose information: for example, how would you "case-insensitivize" {'a': 23, 'A': 45}
?! If all you care is where a key is in the dict or not (i.e., don't care about what value corresponds to it), then make a set
instead -- i.e.
theset = set(k.lower() for k in thedict)
(in every version of Python, or {k.lower() for k in thedict}
if you're happy with your code working only in Python 2.7 or later for the sake of some purely decorative syntax sugar;-), and check with if k.lower() in theset: ...
.
Or, you could make a wrapper class, e.g., maybe a read-only one...:
import collections
class CaseInsensitiveDict(collections.Mapping):
def __init__(self, d):
self._d = d
self._s = dict((k.lower(), k) for k in d)
def __contains__(self, k):
return k.lower() in self._s
def __len__(self):
return len(self._s)
def __iter__(self):
return iter(self._s)
def __getitem__(self, k):
return self._d[self_s[k.lower()]]
def actual_key_case(self, k):
return self._s.get(k.lower())
This will keep (without actually altering the original dictionary, so all precise information can still be retrieve for it, if and when needed) an arbitrary one of possibly-multiple values for keys that "collapse" into a single key due to the case-insensitiveness, and offer all read-only methods of dictionaries (with string keys, only) plus an actual_key_case
method returning the actual case mix used for any given string key (or None
if no case-alteration of that given string key matches any key in the dictionary).