New from old dictionary with combination of specific values with appropriate keys

Viewed 62

In this example, I have a dictionary of the form:

d = {1: {'z': 1, 'x': 11, 'y': 101},
     2: {'z': 2, 'x': 12, 'y': 102},
     3: {'z': 3, 'x': 13, 'y': 103}}

Note:In realty the integer values of z, x, and y are lists or arrays.

The intention is to (possibly with itertools) combine all the z values and form a new dictionary of the form:

new_dict = {12: {'p':(z1 + z2)},
            13: {'p':(z1 + z3)},
            23: {'p':(z2 + z3}}}

Here, z1 corresponds to sub-dictionary 1 with value z, z2 corresponds to sub-dictionary 2 with value z, z3 corresponds to sub-dictionary 3 with value z.


My attempt: I based my idea on extracting the values to first form a list. I an then form the combinations c from this list and populate a new dictionary with them.

# form list of values.
new_dict = {}
new_list = []
for k in d:
    new_list.append(d[k]['z'])

# populate new dictionary.
for n, c in enumerate(itertools.combinations(new_list, 2)):
    new_dict[n] = sum(c)

This gives me:

new_dict = {0: 3, 1: 4, 2: 5}

I would then want to rename the keys (mydict[new_key] = mydict.pop(old_key)) to correspond to the appropriate combinations. In order to later append new information, I would also need to save the information as a sub-dictionary.

final_dict = {12: {'p':3}, 
              13: {'p':4},
              23: {'p':5}}

This is so I can easily track where the information has come from and later append new date to that combination. I'm not sure how I would do this in an iterative way to reflect where the data came from, or if this is the fastest/simplest route.

Note: I was unable to find an answer in How to generate all combination from values in dict of lists in Python or Python: dict comprehensions: making a new dictionary with new values from old dictionary ids. Though they do provide ideas.

1 Answers

You can use itertools.combinations to achieve your goal:

from itertools import combinations

d = {1: {'z': 1, 'x': 11, 'y': 101},
     2: {'z': 2, 'x': 12, 'y': 102},
     3: {'z': 3, 'x': 13, 'y': 103}}

new_dict = {}
for d1, d2 in combinations(d, 2):
    new_dict[int(str(d1) + str(d2))] = {'p': d[d1]['z'] + d[d2]['z']}

print(new_dict)
{12: {'p': 3}, 13: {'p': 4}, 23: {'p': 5}}
Related