Skip to content

Instantly share code, notes, and snippets.

@jaysonsantos
Last active March 17, 2021 19:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jaysonsantos/f0608a413e45b78343bc0e80f91a89cd to your computer and use it in GitHub Desktop.
Save jaysonsantos/f0608a413e45b78343bc0e80f91a89cd to your computer and use it in GitHub Desktop.
Yet another CaseInsensitiveDict implementation
class CaseInsensitiveDict(dict):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.__map = {}
mapping = args[0] if len(args) else {}
keys = set()
if isinstance(mapping, dict):
keys |= mapping.keys()
elif isinstance(mapping, (list, tuple)):
keys |= {key for key, *_ in mapping}
else:
raise ValueError('Mapping must be either a dict or a list/tuple')
keys |= kwargs.keys()
for key in keys:
self.__map[self.__key_name(key)] = key
@staticmethod
def __key_name(item):
return item.lower() if isinstance(item, str) else item
def __getitem__(self, item):
return dict.__getitem__(self, self.__map[self.__key_name(item)])
def __setitem__(self, item, value):
key = self.__key_name(item)
if key in self.__map:
# Delete old key before setting the new one to avoid duplicates
dict.__delitem__(self, self.__map[key])
self.__map[key] = item
dict.__setitem__(self, item, value)
if __name__ == '__main__':
a = CaseInsensitiveDict({'b': 'c'})
a['A'] = 'b'
assert a.keys() == {'b', 'A'}, a.keys()
assert a['A'] == 'b'
a['a'] = 'b'
assert a['a'] == 'b'
assert a.keys() == {'b', 'a'}, a.keys()
a['B'] = 'c'
assert a['B'] == 'c'
assert a.keys() == {'B', 'a'}, a.keys()
b = CaseInsensitiveDict([('A', 'b'), ('c', 'd')])
b['a'] = 'b'
assert b.keys() == {'a', 'c'}
c = CaseInsensitiveDict(A='b', c='d')
c['a'] = 'b'
assert c.keys() == {'a', 'c'}, c.keys()
@pedrospdc
Copy link

que gambeta

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment