1
votes

I have two dictionaries (dict1, dict2) with 100 same keys but different lists of tuples as values:

dict1 = {'M1': [(50, 'M'), (4, 'K')], 'N2': [(500, 'N'), (3, 'C'), (7, 'K')], 'S3': ...}

dict2 = {'M1': [(46, 'M'), (2, 'K'), (11, 'F')], 'N2': [(400, 'N'), (5, 'C')], 'S3': ...}

I want to create a new dictionary (dict3) in which the values are added if they have the same letter in first position of tuple and if not the tuple has to be added to the values of the new dictionary:

dict3 = {'M1': [(96, 'M'), (6, 'K'), (11, 'F')], 'N2': [(900, 'N'), (8, 'C'), (7, 'K)], 'S3': ...}

I was thinking about something like this with python3 (this code does not work):

dict1 = {'M1': [(50, 'M'), (4, 'K')], 'N2': [(500, 'N'), (3, 'C'), (7, 'K')]}
dict2 = {'M1': [(46, 'M'), (2, 'K'), (11, 'F')], 'N2': [(400, 'N'), (5, 'C')]}
dict3 = {} 
for (val1, key1), (val2, key2) in zip(dict1, dict2): 
    if t1[1]==t2[1] for (t1, t2) in (key1, key2):
        t3_0 = t1[0] + t2[0]
        t3_1 = t1[1]
    elif t1[1] not in t2[1]:
        t3_0 = t1[0]
        t3_1 = t1[1]
    elif t2[1] not in t1[1]
        t3_0 = t2[0]
        t3_1 = t2[1]
    key3 = [(t3_0, t3_1)] 
    # here val1=val2 
    dict3[val1] = key3

I would appreciate your help very much. Thank you.

1
"this code does not work" - this is not a problem description. How exactly does it not work? BTW, zip(dict1, dict2) will iterate over the keys of each dictionary, which are strings and thus cannot be unpacked with (val1, key1).ForceBru
If you can re-organize the inner values to be lists of dicts instead of lists of tuples (with the letter as the key) you can greatly improve the time-complexityDeepSpace

1 Answers

1
votes

There are probably a few ways to do this. A relatively simple way you can do this is to construct dictionaries out of the inner lists of tuples - made slightly complicated by the fact the key-value pairings are backwards.

Here is a way to do this:

from collections import defaultdict

# Here is your test data
dict1 = {'M1': [(50, 'M'), (4, 'K')], 'N2': [(500, 'N'), (3, 'C'), (7, 'K')]}
dict2 = {'M1': [(46, 'M'), (2, 'K'), (11, 'F')], 'N2': [(400, 'N'), (5, 'C')]

# This dictionary will be you output
dict3 = defaultdict(list)


def generate_inner_dict(lst):
    """This helper takes a list of tuples and returns them as a dict"""
    # I used a defaultdict again here because your example doesn't always have
    # the same letters in each list of tuples. This will default to zero!
    inner_dict = defaultdict(int)
    for num, key in lst:
        inner_dict[key] = num  # Note that the key and value are flipped
    
    return inner_dict

# loop over the keys in one dictionary - i'm assuming the outer keys are the same
for key in dict1:
    # use the helper to get two dicts
    vals1 = generate_inner_dict(dict1[key])
    vals2 = generate_inner_dict(dict2[key])

    # loop over the keys...
    for inner_key in vals1:
        value = vals1[inner_key] + vals2[inner_key]  # add them together...
        dict3[key].append((inner_key, value))  # and put them in the dictionary

# I turned the defaultdict back into a dict so it looks more obviously like your example
print(dict(dict3))