Skip to content

Instantly share code, notes, and snippets.

@JokerMartini
Last active June 18, 2022 18:04
Show Gist options
  • Save JokerMartini/c3a38069020480727e5e to your computer and use it in GitHub Desktop.
Save JokerMartini/c3a38069020480727e5e to your computer and use it in GitHub Desktop.
Python: Renames recursively every key in a dictionary to lowercase.
import sys
data = {
'MIKE' : ['Great'],
'SUE' : ['happy'],
'JAN' : ['sad']
}
for k, v in data.items():
print k, v
def renameKey(iterable, oldkey, newKey):
if type(iterable) is dict:
for key in iterable.keys():
if key == oldkey:
iterable[newKey] = iterable.pop(key)
return iterable
data = renameKey(data, 'MIKE', 'JokerMartini')
for k, v in data.items():
print k, v
import sys
data = {
'MIKE' : ['Great'],
'SUE' : ['happy'],
'JAN' : ['sad']
}
for k, v in data.items():
print k, v
def renameKeysToLower(iterable):
if type(iterable) is dict:
for key in iterable.keys():
iterable[key.lower()] = iterable.pop(key)
if type(iterable[key.lower()]) is dict or type(iterable[key.lower()]) is list:
iterable[key.lower()] = renameKeysToLower(iterable[key.lower()])
elif type(iterable) is list:
for item in iterable:
item = renameKeysToLower(item)
return iterable
data = renameKeysToLower(data)
for k, v in data.items():
print k, v
@paul-albert
Copy link

paul-albert commented Aug 29, 2020

In line 16 it's better to use:

...
            if type(iterable[key.lower()]) in (dict, list):
...

@bahamut45
Copy link

Python 3.8 exception:

UNEXPECTED EXCEPTION: RuntimeError('dictionary keys changed during iteration')
Traceback (most recent call last):
  File "C:\Python38\lib\doctest.py", line 1336, in __run
    exec(compile(example.source, filename, "single",
  File "<doctest ksc_api.utils.dict_rename_key[1]>", line 1, in <module>
  File "C:\python\utils.py", line 60, in dict_rename_key
    for key in iterable.keys():
RuntimeError: dictionary keys changed during iteration

Fix with :

def dict_rename_key(iterable, old_key, new_key):
    """
    dict_rename_key method

    Args:
        iterable (dict): [description]
        old_key (string): [description]
        new_key (string): [description]

    Returns:
        dict: [description]

    Examples:

    >>> data = {'MIKE': 'test', 'JOHN': 'doe'}
    >>> data_modified = dict_rename_key(data, 'MIKE', 'mike')
    >>> assert 'mike' in data_modified

    """
    if isinstance(iterable, dict):
        for key in list(iterable.keys()):
            if key == old_key:
                iterable[new_key] = iterable.pop(key)
    return iterable

@fred-yu-2013
Copy link

fred-yu-2013 commented Mar 15, 2022

line #20 have no effect on the list items. Try to replace lines #19 and #20 with this:

    return [renameKeysToLower(item) for item in iterable

@hunkim
Copy link

hunkim commented Jun 18, 2022

@bahamut45 If you really want to recursively, I think this would be the way:

def dict_rename_key(iterable, old_key, new_key):
    """
    dict_rename_key method

    Args:
        iterable (dict): [description]
        old_key (string): [description]
        new_key (string): [description]

    Returns:
        dict: [description]

    Examples:

    >>> data = {'MIKE': 'test', 'JOHN': 'doe'}
    >>> data_modified = dict_rename_key(data, 'MIKE', 'mike')
    >>> assert 'mike' in data_modified

    """
    if isinstance(iterable, dict):
        for key in list(iterable.keys()):
            if key == old_key:
                iterable[new_key] = dict_rename_key(iterable.pop(key), old_key, new_key)
            else:
                iterable[key] = dict_rename_key(iterable.pop(key), old_key, new_key)
    return iterable

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