Case insensitive dictionary

后端 未结 10 2418
栀梦
栀梦 2020-11-27 14:47

I\'d like my dictionary to be case insensitive.

I have this example code:

text = \"practice changing the color\"

words = {\'color\': \'colour\',
            


        
10条回答
  •  温柔的废话
    2020-11-27 15:22

    I've modified the simple yet good solution by pleasemorebacon (thanks!) making it slightly more compact, self-contained and with minor updates to allow construction from {'a':1, 'B':2} and support __contains__ protocol. Finally, since the CaseInsensitiveDict.Key is expected to be string (what else can be case-sensitive or not), it is a good idea to derive Key class from the str, then it is possible, for instance, to dump CaseInsensitiveDict with json.dumps out of the box.

    # caseinsensitivedict.py
    class CaseInsensitiveDict(dict):
    
        class Key(str):
            def __init__(self, key):
                str.__init__(key)
            def __hash__(self):
                return hash(self.lower())
            def __eq__(self, other):
                return self.lower() == other.lower()
    
        def __init__(self, data=None):
            super(CaseInsensitiveDict, self).__init__()
            if data is None:
                data = {}
            for key, val in data.items():
                self[key] = val
        def __contains__(self, key):
            key = self.Key(key)
            return super(CaseInsensitiveDict, self).__contains__(key)
        def __setitem__(self, key, value):
            key = self.Key(key)
            super(CaseInsensitiveDict, self).__setitem__(key, value)
        def __getitem__(self, key):
            key = self.Key(key)
            return super(CaseInsensitiveDict, self).__getitem__(key)
    

    Here is a basic test script for those who like to check things in action:

    # test_CaseInsensitiveDict.py
    import json
    import unittest
    from caseinsensitivedict import *
    
    class Key(unittest.TestCase):
        def setUp(self):
            self.Key = CaseInsensitiveDict.Key
            self.lower = self.Key('a')
            self.upper = self.Key('A')
    
        def test_eq(self):
            self.assertEqual(self.lower, self.upper)
    
        def test_hash(self):
            self.assertEqual(hash(self.lower), hash(self.upper))
    
        def test_str(self):
            self.assertEqual(str(self.lower), 'a')
            self.assertEqual(str(self.upper), 'A')
    
    class Dict(unittest.TestCase):
        def setUp(self):
            self.Dict = CaseInsensitiveDict
            self.d1 = self.Dict()
            self.d2 = self.Dict()
            self.d1['a'] = 1
            self.d1['B'] = 2
            self.d2['A'] = 1
            self.d2['b'] = 2
    
        def test_contains(self):
            self.assertIn('B', self.d1)
            d = self.Dict({'a':1, 'B':2})
            self.assertIn('b', d)
    
        def test_init(self):
            d = self.Dict()
            self.assertFalse(d)
            d = self.Dict({'a':1, 'B':2})
            self.assertTrue(d)
    
        def test_items(self):
            self.assertDictEqual(self.d1, self.d2)
            self.assertEqual(
                [v for v in self.d1.items()],
                [v for v in self.d2.items()])
    
        def test_json_dumps(self):
            s = json.dumps(self.d1)
            self.assertIn('a', s)
            self.assertIn('B', s)
    
        def test_keys(self):
            self.assertEqual(self.d1.keys(), self.d2.keys())
    
        def test_values(self):
            self.assertEqual(
                [v for v in self.d1.values()],
                [v for v in self.d2.values()])
    

提交回复
热议问题