tcokyasar
tcokyasar

Reputation: 592

Adding dictionary values with the missing values in the keys

I have the following three dictionaries:

Mydict = {'(1)': 850.86,
          '(1, 2)': 1663.5,
          '(1, 2, 3)': 2381.67,
          '(1, 3)': 1568.89,
          '(2)': 812.04,
          '(2, 3)': 1529.45,
          '(3)': 717.28}

A = {1: 4480.0, 2: 3696.0, 3: 4192.5}
B = {1: 1904.62, 2: 1709.27, 3: 1410.73}

Based on the keys in Mydict, I want to add the missing key value of min(A, B). For example, For the first key '(1)' in Mydict, I want to add min(A[2], B[2]) + min(A[3], B[3]) to the value of the first row and update the value in that dictionary. Similarly, for the value of the key: '(1, 2)', I want to add the min(A[3] + B[3]) as only 3 is missing in there. For '(1, 2, 3)', I don't need to add anything as it involves all the 3 numbers, namely 1, 2, and 3.Thus, my new Mydict will be as following:

Mynewdict = {'(1)': 3970.86,
              '(1, 2)': 3074.23,
              '(1, 2, 3)': 2381.67,
              '(1, 3)': 3278.16,
              '(2)': 4127.39,
              '(2, 3)': 3434.07,
              '(3)': 4331.17}

In this example, all the values of B are less than the values of A, however, it may not be the case for all the time, that is why, I want to add the minimum of those. Thanks for answers.

Upvotes: 1

Views: 94

Answers (1)

atru
atru

Reputation: 4744

The list of numbers sounds like a good idea, but to me it seems it will still require similar amount of (similar) operations as the following solution:

import re

str_pat = re.compile(r'\((.*)\)')

Mynewdict = Mydict
for key in Mynewdict.keys():

    match = (str_pat.findall(key)[0]).split(',')

    # set(list(map(int, match))) in Python 3.X
    to_add = list(set(A.keys()).difference(set(map(int,match))))

    if to_add:
        for kAB in to_add:
            Mynewdict[key] += min(A[kAB],B[kAB])

For each key in Mynewdict this program finds the pattern between the brackets and turns it into a list match split by ,. This list is then compared to list of keys in A.

The comparison goes through sets - the program construct sets from both lists and returns a set difference (also turned into list) into to_add. to_add is hence a list with keys in A that are numbers not present in the compound key in Mynewdict. This assumes that all the keys in B are also present in A. map is used to convert the strings in match to integers (for comparison with keys in A that are integers). To use it in Python 3.X you need to additionally turn the map(int, match) into a list as noted in the comment.

Last part of the program assigns minimum value between A and B for each missing key to the existing value of Mynewdict. Since Mynewdict is initially a copy of Mydict all the final keys and intial values already exist in it so the program does not need to check for key presence or explicitly add the initial values.

To look for keys in Mynewdict that correspond to specific values it seems you actually have to loop through the dictionary:

find_val = round(min(Mynewdict.values()),2)
for key,value in Mynewdict.items():
    if find_val == round(value,2):
        print key, value

What's important here is the rounding. It is necessary since the values in Mynewdict have variable precision that is often longer than the precision of the value you are looking for. In other words without round(value,2) if will evaluate to False in cases where it is actually True.

Upvotes: 1

Related Questions