iterate 2 dicts and compare values then append inner list

Viewed 46

I am faced with a situation where I need to iterate nested dicts with same outermost keys, compare inner key value to inner key value of other dict then append. Below will help to understand:

{AD:{(62,'VMX','Barcelona','ES'): ['123','567','666'}} #dict1  many more rows

{AD:{(151,'CMXS','','ES','62'): ['345','6754']}}       #dict 2 many more rows

So I need to iterate both dicts, compare tuple key[0] of dict1 == tuple key[4] of dict2, if they match append inner list in dict1 with inner list in dict2.

after this dict1 looks like

{AD:{(62,'VMX','Barcelona','ES'): ['123','567','666','345','6754'}}

Wrote this code but it not working as expected

for k,v in dict1.items():
    if len(v)!= 0:
        for c,a in dict2.items():
            if len(a)!= 0:
                for k2,v2 in v.items():
                    for c2,a2 in a.items():
                        if str(k2[0]) == c2[4]:
                            v2.append(a2)

2 Answers
dict1 = {"AD":{(62,'VMX','Barcelona','ES'): ['123','567','666']}} #dict1  many more rows

dict2 = {"AD":{(151,'CMXS','','ES','62'): ['345','6754']}}       #dict 2 many more rows

# create a simplified map of dict2
dict3 = {}
for outer_key, outer_value_dict in dict2.items():
    for inner_key_tuple, inner_value_list in outer_value_dict.items():
        new_key = (outer_key, inner_key_tuple[4]) # e.g. (AD, 62)
        dict3.setdefault(new_key, []).extend(inner_value_list)

# now modify dict1 using dict3 instead of dict2
for outer_key, outer_value in dict1.items():
    for inner_key_tuple, inner_value_list in outer_value.items():
        lookup_key = (outer_key, str(inner_key_tuple[0]))
        # search dict3 using the lookup_key.
        # if not present, get will return an empty list
        list_to_extend = dict3.get(lookup_key, [])
        inner_value_list.extend(list_to_extend)

print(dict1)

Output

/tmp $ python test.py.py
{'AD': {(62, 'VMX', 'Barcelona', 'ES'): ['123', '567', '666', '345', '6754']}}

Based on the comments, since you wanted to know how to avoid one of the loops - here's an updated version

for k,v in dict1.items():
    a = dict2.get(k)
    if a is None or len(v) == 0:
        continue

    for k2,v2 in v.items():
        for c2,a2 in a.items():
            if str(k2[0]) == c2[4]:
                v2.append(a2)

The for loops are placed correctly as long as the example goes.

What do you mean by unexpectedly? Do you mean this?

{'AD': {(62, 'VMX', 'Barcelona', 'ES'): ['123', '567', '666', ['345', '6754']]}}

That extra array within the array?

Because if so, the answer would be to switch the .append() with a .extend()

Related