Anubhav
Anubhav

Reputation: 585

How to expand a dictionary to incorporate all matching values?

I have a dictionary as such:

{
    'key1': [1,2,3],
    'key2': [4,5,6],
    '1': [4,5],
    '4': [4,6]
}

Now, I need to unpack this dictionary so all values that also occur as keys get appended to the original key. By that I mean the result should be:

{
    'key1': [1,2,3,4,5,6],
    'key2': [4,5,6]
    '1': [4,5,6]
    '4': [4,6]
}

Basically the 1 value in key1 has a key-value pair in of {'1':[4,5,6]}. So I need that appended to the original key1. Then the 4 also has a corresponding key-value pair so that should also get appended to key1 as key1 now has 4.

Note I don't know the "depth" of the dictionary before hand. So I need a solution scalable to arbitrary depth

So far I have tried this:

new_dict = {}
def expand(dict):
    for k in dict:
        for dep in dict[k]:
            val = dict.get(dep)
            new_dict[k] = [dep, val]
    return new_dict

But this solution can only go 2 depths. And I am not sure how to go about capturing more matches of keys across arbitrary depths.

Upvotes: 3

Views: 118

Answers (1)

blhsing
blhsing

Reputation: 106638

You can use a while loop to keep expanding each sub-list of the dict with items in matching keys from the items that are not in the old sub-list. Use sets to obtain such deltas efficiently:

def expand(d):
    for lst in d.values():
        old = set()
        new = set(lst)
        while True:
            delta = new - old
            if not delta:
                break
            old = new.copy()
            for i in map(str, delta):
                if i in d:
                    new.update(d[i])
        lst[:] = new
    return d

so that given your sample input as variable d, expand(d) returns:

{'key1': [1, 2, 3, 4, 5, 6], 'key2': [4, 5, 6], '1': [4, 5, 6], '4': [4, 6]}

Upvotes: 1

Related Questions