Python recursively replace character in keys of nested dictionary? Python recursively replace character in keys of nested dictionary? python python

Python recursively replace character in keys of nested dictionary?


Yes, there exists better way:

def print_dict(d):    new = {}    for k, v in d.iteritems():        if isinstance(v, dict):            v = print_dict(v)        new[k.replace('.', '-')] = v    return new

(Edit: It's recursion, more on Wikipedia.)


Actually all of the answers contain a mistake that may lead to wrong typing in the result.

I'd take the answer of @ngenain and improve it a bit below.

My solution will take care about the types derived from dict (OrderedDict, defaultdict, etc) and also about not only list, but set and tuple types.

I also do a simple type check in the beginning of the function for the most common types to reduce the comparisons count (may give a bit of speed in the large amounts of the data).

Works for Python 3. Replace obj.items() with obj.iteritems() for Py2.

def change_keys(obj, convert):    """    Recursively goes through the dictionary obj and replaces keys with the convert function.    """    if isinstance(obj, (str, int, float)):        return obj    if isinstance(obj, dict):        new = obj.__class__()        for k, v in obj.items():            new[convert(k)] = change_keys(v, convert)    elif isinstance(obj, (list, set, tuple)):        new = obj.__class__(change_keys(v, convert) for v in obj)    else:        return obj    return new

If I understand the needs right, most of users want to convert the keys to use them with mongoDB that does not allow dots in key names.


I used the code by @horejsek, but I adapted it to accept nested dictionaries with lists and a function that replaces the string.

I had a similar problem to solve: I wanted to replace keys in underscore lowercase convention for camel case convention and vice versa.

def change_dict_naming_convention(d, convert_function):    """    Convert a nested dictionary from one convention to another.    Args:        d (dict): dictionary (nested or not) to be converted.        convert_function (func): function that takes the string in one convention and returns it in the other one.    Returns:        Dictionary with the new keys.    """    new = {}    for k, v in d.iteritems():        new_v = v        if isinstance(v, dict):            new_v = change_dict_naming_convention(v, convert_function)        elif isinstance(v, list):            new_v = list()            for x in v:                new_v.append(change_dict_naming_convention(x, convert_function))        new[convert_function(k)] = new_v    return new