Search code examples
pythondictionaryordereddictionary

change key to lower case for dict or OrderedDict


Following works for a dictionary, but not OrderedDict. For od it seems to form an infinite loop. Can you tell me why? If the function input is dict it has to return dict, if input is OrderedDict it has to return od.

def key_lower(d):
    """returns d for d or od for od with keys changed to lower case
    """
    for k in d.iterkeys():
        v = d.pop(k)
        if (type(k) == str) and (not k.islower()):
            k = k.lower()
        d[k] = v

    return d

Solution

  • It forms an infinite loop because of the way ordered dictionaries add new members (to the end)

    Since you are using iterkeys, it is using a generator. When you assign d[k] = v you are adding the new key/value to the end of the dictionary. Because you are using a generator, that will continue to generate keys as you continue adding them.

    You could fix this in a few ways. One would be to create a new ordered dict from the previous.

    def key_lower(d):
         newDict = OrderedDict()
        for k, v in d.iteritems():
            if (isinstance(k, (str, basestring))):
                k = k.lower()
            newDict[k] = v
        return newDict
    

    The other way would be to not use a generator and use keys instead of iterkeys