0

I'm fairly new to python world and found it very interesting thus far, however, finding difficulties with the use case below, any help is appreciated.

I have 2 dict's which has same keys but different values, using set via symmetric difference I was able to get a list of tuples from the 2 dicts, but not sure how I could transform it to a result that i'm expecting.

mydict1 = {
    "KMSKeyId": "arn:aws:kms:us-east-1:12345:alias/key_name",
    "Subnets": "subnet-123,subnet-456",
    "VpcId": "vpc-123",
    "Region": "us-east-1",
    "SecurityGroups": "sg-123,sg-456",
    "ProxyHost": "my-custom-proxy-us-east-1.aws.com"
}
mydict2 = {
    "KMSKeyId": "arn:aws:kms:us-west-1:12345:alias/key_name",
    "Subnets": "subnet-789,subnet-1011",
    "VpcId": "vpc-456",
    "SecurityGroups": "sg-789,sg-1011",
    "Region": "us-west-1",
    "ProxyHost": "my-custom-proxy-us-west-1.aws.com"
}

Expected result

result = {
   "us-east-1": {
      "KMSKeyId": "arn:aws:kms:us-east-1:12345:alias/key_name",
      "Subnets": "subnet-123,subnet-456",
      "VpcId": "vpc-123",
      "SecurityGroups": "sg-123,sg-456",
      "ProxyHost": "my-custom-proxy-us-east-1.aws.com"
   },
   "us-west-1": {
      "KMSKeyId": "arn:aws:kms:us-west-1:12345:alias/key_name",
      "Subnets": "subnet-789,subnet-1011",
      "VpcId": "vpc-456",
      "SecurityGroups": "sg-789,sg-1011",
      "ProxyHost": "my-custom-proxy-us-west-1.aws.com"
   }
}
print(list(set(mydict1.items()) ^ set(mydict2.items()))) yields ----> 
 [('SecurityGroups', 'sg-789,sg-1011'), 
  ('ProxyHost', 'my-custom-proxy-us-east-1.aws.com'), 
  ('Subnets', 'subnet-123,subnet-456'), 
  ('SecurityGroups', 'sg-123,sg-456'), 
  ('Subnets', 'subnet-789,subnet-1011'), 
  ('KMSKeyId', 'arn:aws:kms:us-west-1:12345:alias/key_name'), 
  ('Region', 'us-east-1'), 
  ('ProxyHost', 'my-custom-proxy-us-west-1.aws.com'), 
  ('VpcId', 'vpc-456'), 
  ('Region', 'us-west-1'), 
  ('KMSKeyId', 'arn:aws:kms:us-east-1:12345:alias/key_name'), 
  ('VpcId', 'vpc-123')]

From the above tuple list, not sure how I could get the expected result. Using the FakeDict described here, https://stackoverflow.com/a/29520802/2101043, was able to get a dict like object that has same keys and different values, however mapping the VPC, subnet and security group to the corresponding region seem to be challenging as a beginner in python

martineau
  • 119,623
  • 25
  • 170
  • 301
Sai
  • 1,790
  • 5
  • 29
  • 51
  • Not sure if I understood the problem correctly but you need something like `{mydict1["Region"]: mydict1, mydict2["Region"]: mydict2}`. – Selcuk Oct 21 '19 at 02:52

2 Answers2

0

You should be able to do this with:

result = {dct["Region"]: {key: dct[key] for key in dct if key != "Region"} for dct in [mydict1, mydict2]}

This makes a dictionary based on the two current dictionaries, keyed on the region, where the value is the original dictionary but with the region removed. Printing the result out after that gives you what you appear to want:

# Generated with:
#    import pprint
#    pprint.PrettyPrinter().pprint(result)
{'us-east-1': {'KMSKeyId': 'arn:aws:kms:us-east-1:12345:alias/key_name',
               'ProxyHost': 'my-custom-proxy-us-east-1.aws.com',
               'SecurityGroups': 'sg-123,sg-456',
               'Subnets': 'subnet-123,subnet-456',
               'VpcId': 'vpc-123'},
 'us-west-1': {'KMSKeyId': 'arn:aws:kms:us-west-1:12345:alias/key_name',
               'ProxyHost': 'my-custom-proxy-us-west-1.aws.com',
               'SecurityGroups': 'sg-789,sg-1011',
               'Subnets': 'subnet-789,subnet-1011',
               'VpcId': 'vpc-456'}}
paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953
0

There are multiple ways of doing same, below is one way of doing which is more maintainable.

import copy

# Generator function
def mergedicts(*arr_dicts):
    for d in arr_dicts:
        # Do dict manipulation with custom logic here
        region_name = d['Region']
        tmpdict = { region_name: copy.deepcopy(d) } # also deep copy if original dict should be intact.
        del tmpdict[region_name]['Region']
        yield tmpdict

values = list( mergedicts(mydict1, mydict2) ) 

print(values)

# OR

for item in mergedicts(mydict1, mydict2):
    print(item)

Advantage of this function is that

  • Your dict manipulation logic kept desperately, can be reused multiple times.
  • This is generator function, it will be a memory efficient and dict manipulation will happen lazily one by one only when required like done in for loop.
RockStar
  • 1,304
  • 2
  • 13
  • 35