Delete items in nested dictionary based on value.

Brian L. Troutwine goofyheadedpunk at gmail.com
Thu Sep 14 01:08:37 CEST 2006


I've got a problem that I can't seem to get my head around and hoped
somebody might help me out a bit:

I've got a dictionary, A, that is arbitarily large and may contains
ints, None and more dictionaries which themselves may contain ints,
None and more dictionaries. Each of the sub-dictionaries is also
arbitrarily large. When pretty printing A, in the context I'm using A
for, it's rather helpful to remove all key:value pairs where value is
None. So I'd like to be able to define a function dict_sweep to recurse
through A and del all the keys with None as a value.

I feel like the solution is right on the tip of my tounge, so to speak,
but I just can't quite get it. Anyway, here's the best I've come up
with:

def dict_sweep(dictionary, key_value):
    """Sweep through dictionary, deleting any key:value where
    value is None.

    """
    # Find key at position key_value.
    key = dictionary.keys()[key_value]

    # If the key value is a dictionary we want to move into it.
    # Therefore we call rec_rem on dictionary[key] with a
    # key_value of 0
    if type(dictionary[key]) is type({}):
        dict_sweep(dictionary[key], 0)

    # If the value isn't a dictionary we care only that it's not None.
    # If it is None we nuke it and call rec_rem on the current
    # dictionary with key_value incrimented by one.
    elif dictionary[key] is None:
        del dictionary[key]
        dict_sweep(dictionary, key_value+1)

    # If the value isn't a dictionary and the value isn't None then
    # we still want to walk through to the next value in the
    # dictionary, so call rec_rem with key_value+1
    else:
        dict_sweep(dictionary, key_value+1)

Assuming dict_sweep worked perfectly it would take input like this:

A_in = {1: {2: 2, 3: {1: None, 2: 2}}, 2: 2, 3: None}

B_in = {1: {1: {1: None, 2: {1: None}}, 2: 2, 3: None}

and output this:

A_out = {1: {2: 2, 3: {2: 2}}, 2: 2}

B_out = {2:2}

This dict_sweep above obviously doesn't work and I'm rather afraid of
hitting python's recursion limit. Does anyone see a way to modify
dict_sweep in it's current state to perform dictionary sweeps like
this? What about a non-recursive implementation of dict_sweep?




More information about the Python-list mailing list