views:

188

answers:

3

If I have a deeply nested dict is there a built-in way to subtract/remove list of "paths" (eg: keyA.keyB.key1, keyA.keyC.key2, etc) or a the keys of a second dict from the original dict? Or maybe there is a common module which has functionality like this?

+2  A: 

Here's a suggestion:

D = { "keyA": { 
        "keyB" : {
            "keyC" : 42,
            "keyD": 13
            },
        "keyE" : 55
        }
    }

def remove_path(dictionary, path):
    for node in path[:-1]:
        dictionary = dictionary[node]
    del dictionary[path[-1]]

remove_path(D, ["keyA", "keyB", "keyD"])

print D # prints {'keyA': {'keyB': {'keyC': 42}, 'keyE': 55}}

You'll probably want to introduce some error checking, too.

balpha
+1  A: 

Another solution:

d = {
    'A' : {
        'C' : {
            'D' : {
                'E' : 4,
            },
            'F' : 5,
        },
    },
    'B' : 2,
}

def DeepDictDel(path, dict):
    for key in path.split('.'):
        owner = dict
        dict = dict[key]

    del owner[key]


print d # prints {'A': {'C': {'D': {'E': 4}, 'F': 5}}, 'B': 2}
DeepDictDel('A.C.D', d)
print d # prints {'A': {'C': {'F': 5}}, 'B': 2}
Bruno Oliveira
This is more like I had imagined (as in, using a "key.key" path), however balpha's answer is also great.
digitala
A: 

Just in case the other answers aren't what you're looking for, here's one that subtracts one dictionary from another.

def subtract(a, b):
    """ Remove the keys in b from a. """
    for k in b:
        if k in a:
            if isinstance(b[k], dict):
                subtract(a[k], b[k])
            else:
                del a[k]
Jason Orendorff