1

I have multiple dictionaries and a base dictionary. I need to iterate through the dictionaries keys and need to check the existing keys and new keys in each iteration but in each iteration, I need to combine all previous keys of dictionary and check with current dictionary key for example


dict10 = {'A':1, 'C':2} #base dictionary
dict11 = {'B':3, 'C':4}
dict12 = {'A':5, 'E':6, 'F':7}

here is the calculation process

Exist_Score = (values of keys in dict11.keys() & dict10.keys()) + (values of keys in dict12.keys() & (dict11.keys() + dict10.keys()))

New_score = (values of keys in dict11.keys() - dict10.keys()) + (values of keys in dict12.keys() - (dict11.keys() + dict10.keys()))

my manual way to calculate the scores

exist_score = 0
new_score = 0


for key in dict11.keys() & dict10.keys():
    exist_score += dict11[key]

for key in dict12.keys() & set(dict11.keys()).union(set(dict10.keys())):
    exist_score += dict12[key]

for key in dict11.keys() - dict10.keys():
    new_score += dict11[key]

for key in dict12.keys() - set(dict11.keys()).union(set(dict10.keys())):
    new_score += dict12[key]

print(exist_score)
print(new_score)

for the given example the score will

Exist_Score = 4 + 5

New_Score = 3 + (6 + 7)

How can I achieve this for a dynamic number of lists and iteratively combine lists to check the keys?

  • `Exist_Score` and `New_score` are computed using something that is not python code. I therefore have no idea what you're trying to compute and am therefore unable to help extend this functionality – inspectorG4dget Jul 24 '19 at 18:41
  • Sorry about that, that's not python code I just explained how it should be achieved for calculation of score – kumaran ragunathan Jul 24 '19 at 18:43
  • The key in common of the first two dictionaries is C, which has a different value for dict10 and dict11. Do you always want to grab the values of the dictionary in the second dict in all of these operations? – alkasm Jul 24 '19 at 18:46
  • @alkasm I always take the value of the current dictionary. For example, if I'm taking dict11 then I will take values in that dict. – kumaran ragunathan Jul 24 '19 at 18:49
  • How are you retrieving the values of 4 and 5 for exist_score. It appears to be taking the maximum value inside the intersection of dict10 and dict 11 + the maximum value of the intersection between dict12 and the union of (dict11+dict10)? – plum 0 Jul 24 '19 at 18:50
  • @plum0 it's not maximum. I'm taking the value from the latest dict, not the past values – kumaran ragunathan Jul 24 '19 at 18:52
  • your formula is very unclear then for what you are trying to implement. I would come up with a better way to present this information without the use of &, since you really want to use dict 11 OR dict 10, which you already know which dictionary you are using beforehand. – plum 0 Jul 24 '19 at 19:13
  • What does "current dictionary" and "latest dictionary" mean? Please elaborate. – alkasm Jul 24 '19 at 19:17
  • @alkasm I have updated the python code you can get the idea from it – kumaran ragunathan Jul 24 '19 at 19:28
  • @plum0 I have updated the python code so that you can get the clear idea about it – kumaran ragunathan Jul 24 '19 at 19:31
  • @inspectorG4dget I have updated the python code. – kumaran ragunathan Jul 24 '19 at 19:32

1 Answers1

1

Using the provided dictionaries, i.e.

dict10 = {'A':1, 'C':2} #base dictionary
dict11 = {'B':3, 'C':4}
dict12 = {'A':5, 'E':6, 'F':7}

We find the keys that are the same with the base dictionary and the keys that are not in the base dictionary, and then calculate the scores using keys in some combined dictionary:

# Combine all three dictionaries into one
dict_combine = dict(dict10, **dict(dict11, **dict12))

# Find keys that are the same with the base dictionary
keys_same = (dict10.keys() & dict11.keys()) | (dict10.keys() & dict12.keys())

# Find keys that are not in the base dictionary
keys_new = dict10.keys() ^ dict11.keys() ^ dict12.keys()

# Calculate scores
exist_score = sum([dict_combine[key] for key in keys_same])
new_score = sum([dict_combine[key] for key in keys_new])

Now, the scores are what we expect:

>> exist_score
9
>> new_score
16

The code can be expanded for more dictionaries as desired.


EDIT:

If the non-base dictionaries do not necessarily have unique keys (i.e. they may share the same key as one-another), you can use this function based on the updated code you provided:

def get_scores(base_dict, *new_dicts):
    # Initialize scores
    exist_score = 0
    new_score = 0

    # Iterate through non-base dictionaries
    for i, i_dict in enumerate(new_dicts):
        # Get base dictionary keys and find unions
        keys = base_dict.keys()
        for j in range(i):
            keys = keys | new_dicts[j].keys()

        # Find keys for existing score and new score
        keys_same = i_dict.keys() & keys
        keys_new = i_dict.keys() - keys

        # Update scores
        exist_score += sum([i_dict[key] for key in keys_same])
        new_score += sum([i_dict[key] for key in keys_new])

    # Return scores as tuple
    return exist_score, new_score

Now, when I run it using your dictionaries, I get the following result:

>> exist_score, new_score = get_scores(dict10, dict11, dict12)
>> exist_score
9
>> new_score
16

This will work for a dynamic number of dictionaries, using the *args notation in the function header. See use of *args and **kwargs.

Stephen B
  • 1,246
  • 1
  • 10
  • 23