1

This is probably a naive question from a programming languages standpoint (the answer must be no).

Was there ever a version of python that had case-insensitive dicts by default?

Ie, if I queried dict['value'] it would be the same as dict['VALUE']?

I just ask because I am working with some code written in Python 3.7, but I am working in Python 3.8.5. I could either just rewrite the code, or try a different version of Python - not sure which will take longer.

Perhaps this is also a function of pandas, which went from pandas 1.0.4 to '1.1.3'. I will check more on this.

Sam Weisenthal
  • 2,791
  • 9
  • 28
  • 66
  • 5
    If I understand you correctly, your problem is that you don't know if dicts behave the same in Python 3.7 and 3.8.5. Please try out whether dicts are case insensitive in either version and share your findings with us. – peer Jan 05 '22 at 20:51
  • 2
    Can you better describe the situation where that behavior would be useful? – OneCricketeer Jan 05 '22 at 20:52
  • 1
    I doubt it, because this would be a severe breaking change, and rather non-sensible in the first place. You should just normalizing the casing of your strings before using them as dictionary keys – Alexander Jan 05 '22 at 20:52
  • @peer - I think of course they are case sensitive. I can try it, but I don't think it is needed. There are questions I see on making them insensitive here – Sam Weisenthal Jan 05 '22 at 20:52
  • "not sure which will take longer" It takes longer to write this question. – Elis Byberi Jan 05 '22 at 20:52
  • 3
    No, such version had never existed. String hash does know nothing about string case, and it would be REALLY strange and unexpected behavior. Dictionaries are not just 'case sensitive', but are sensitive for any change in key. Key instances must be hashable and comparable, and no, string equality was never case-ignoring. – STerliakov Jan 05 '22 at 20:52
  • ok thank you all - I can remove the question – Sam Weisenthal Jan 05 '22 at 20:53
  • Could you show a piece of code (better isolated MRE) where this happened? – STerliakov Jan 05 '22 at 20:53
  • I don't think I should @SUTerliakov, you answered my question. I think it's just two scripts that are not in sync with respect to the cases of the keys – Sam Weisenthal Jan 05 '22 at 20:56
  • 2
    Python has never had "case-insensitive" dictionaries (assuming the keys are strings). However the keys can be any hashable objects, even a mixture of different types, so you question make little sense. – martineau Jan 05 '22 at 21:24

2 Answers2

2

I don't know of any previous version of Python that did this, but you could probably make your own dictionary type that does it pretty easily.

class UncasedDict(dict):                                                        
    def __getitem__(self, key):                                                 
        if isinstance(key, str):                                                
            key = key.lower()                                                   
        return super().__getitem__(key)                                         
                                                                                
    def __setitem__(self, key, value):                                          
        if isinstance(key, str):                                                
            key = key.lower()                                                   
        return super().__setitem__(key, value)                                  
                                                                                
                                                                                
d = UncasedDict()                                                               
                                                                                
d["hello"] = 1                                                                  
print(f'{d["hello"]=}')                                                         
print(f'{d["helLo"]=}')                                                         
                                                                                
d["GOODBYE"] = 2                                                                
print(f'{d["GOODBYE"]=}')                                                       
print(f'{d["GoOdByE"]=}')  

                                                 

# d["hello"]=1
# d["helLo"]=1
# d["GOODBYE"]=2
# d["GoOdByE"]=2

The idea is to just intercept key when you get/set the dictionary values and replace it with key.lower(). You would want to do this for each capability of dicts that you use, e.g., __delitem__(), __contains__(), etc.

user1717828
  • 7,122
  • 8
  • 34
  • 59
  • Your subclass implementation would be a lot better IMO if you made the abstract base class [`collections.abc.MutableMapping`](https://docs.python.org/3/library/collections.abc.html?highlight=mutablemapping#collections-abstract-base-classes) as its base because doing so would provide more of the functionality that regular dictionaries have (without requiring every one of its methods to be re-implemented). – martineau Jan 07 '22 at 14:14
-1

Dictionaries are mutable unordered collections (they do not record element position or order of insertion) of key-value pairs. Keys within the dictionary must be unique and must be hashable. That includes types like numbers, strings and tuples. Lists and dicts can not be used as keys since they are mutable. Dictionaries in other languages are also called hash tables or associative arrays.

Numeric types used for keys obey the normal rules for numeric comparison: if two numbers compare equal (such as 1 and 1.0) then they can be used interchangeably to index the same dictionary entry.

Reference: dict

Franz Kurt
  • 1,020
  • 2
  • 14
  • 14
  • _Performing list(d) on a dictionary returns a list of all the keys used in the dictionary, in insertion order..._, [Reference](https://docs.python.org/3/tutorial/datastructures.html#dictionaries). – user1717828 Jan 05 '22 at 21:09