Search code examples
pythonpython-3.xdictionaryprepend

Prepend all values in deeply nested dictionary


I have a deeply nested dictionary (arbitrary keys and values) like:

data = {
    'a': {
        'path': '/a/a.txt'
    },
    'b': {
        'b1': {
            'path': '/b/b1/b1.txt'
        },
        'b2': {
            'path': '/b/b2/b2.txt'
        }
    }
    'c': {
        'c1': {
            'c12': {
                'path': '/c/c1/c12/c12.txt'
            }
        },
        'c2': {
            'c22': {
                'path': '/c/c1/c22/c22.txt'
            }
        },
        'c3': {
            'c32': {
                'path': '/c/c1/c32/c32.txt'
            }
        }
    }
    .
    .
    .
}

My goal is to prepend every value in the dictionary with a specific path. So basically take in the data above, operate on it:

def prepend(value, data):
    return magic

data = prepend('predir/z', data)

and have the resulting dict look like:

data = {
    'a': {
        'path': 'predir/z/a/a.txt'
    },
    'b': {
        'b1': {
            'path': 'predir/z/b/b1/b1.txt'
        },
        'b2': {
            'path': 'predir/z/b/b2/b2.txt'
        }
    }
    'c': {
        'c1': {
            'c12': {
                'path': 'predir/z/c/c1/c12/c12.txt'
            }
        },
        'c2': {
            'c22': {
                'path': 'predir/z/c/c1/c22/c22.txt'
            }
        },
        'c3': {
            'c32': {
                'path': 'predir/z/c/c1/c32/c32.txt'
            }
        }
    }
    .
    .
    .
}

I know I can use recursion to loop through the dict like so:

def prepend(directory, config):
    for k, v in config.items():
        if isinstance(v, dict):
            prepend(directory, v)
        else:
            # do something

But, I'm not able to change the values during iteration. Any and all help is greatly appreciated! Thank you!


Solution

  • In the else branch, just add the prefix to the existing value, and store it in the key :

    def prepend(directory, config):
        for k, v in config.items():
            if isinstance(v, dict):
                prepend(directory, v)
            else:
                config[k] = directory + v
        return config