Home > Software design >  Pythonic way toCompare two Dictionaries and Append Nested Object where keys match
Pythonic way toCompare two Dictionaries and Append Nested Object where keys match

Time:09-17

Python newbie with working code, but looking to learn if there is a better way.

Problem statement - One python dictionary contains details about volumes, and a second contains details about snapshots of the volumes. Produce a json document with each volume as a key and if there are snapshots for that volume, add the snapshot dictionary object as a nested dictionary under the Snapshots key of the corresponding volume. If the volume does not have any snapshots, simply append an empty object as a nested dictionary under the Snapshots key of the corresponding volume.

  1. Is there a more pythonic way to solve this challenge (perhaps comprehension)?
  2. Am I making mistake by updating the original dictionary?
import json
volume_dict = {
    "vol-04f": {
        "Name": "db_server",
        "State": "in-use",
        "DataType": "Public",
        "Attachments": [
            "i-0fc"
        ]
    },
    "vol-0cc": {
        "Name": "app_server",
        "State": "in-use",
        "DataType": "Public",
        "Attachments": [
            "i-051"
        ]
    }
}

# Snapshot Dictionary
snapshot_dict = {
    "vol-04f": [
        {
            "snap-0086": {
                "Date": 20210911,
                "SnapshotState": "completed"
            }
        },
        {
            "snap-06ff": {
                "Date": 20210910,
                "SnapshotState": "completed"
            }
        },
        {
            "snap-0263": {
                "Date": 20210919,
                "SnapshotState": "completed"
            }
        }
    ]
}

for volume_key, volume_value in volume_dict.items():
    if volume_key in snapshot_dict:
        value = {}
        snapshot_value = snapshot_dict.get(volume_key)
        value["Snapshots"] = snapshot_value
    else:
        value = {}
        value["Snapshots"] = {}
    volume_dict[volume_key].update(value)

print(json.dumps(volume_dict))

Desired Output

{
    "vol-04f": {
        "DataType": "Public",
        "State": "in-use",
        "Name": "db_server",
        "Snapshots": [
            {
                "snap-0086": {
                    "Date": 20210911,
                    "SnapshotState": "completed"
                }
            },
            {
                "snap-06ff": {
                    "Date": 20210910,
                    "SnapshotState": "completed"
                }
            },
            {
                "snap-0263": {
                    "Date": 20210919,
                    "SnapshotState": "completed"
                }
            }
        ],
        "Attachments": [
            "i-0fc"
        ]
    },
    "vol-0cc": {
        "DataType": "Public",
        "State": "in-use",
        "Name": "app_server",
        "Snapshots": {},
        "Attachments": [
            "i-051"
        ]
    }
}

CodePudding user response:

dict.get has default value that's returned when key is not found, you can take advantage of it:

for k, v in volume_dict.items():
    v["Snapshots"] = snapshot_dict.get(k, {})

print(volume_dict)

Prints:

{
    "vol-04f": {
        "Name": "db_server",
        "State": "in-use",
        "DataType": "Public",
        "Attachments": ["i-0fc"],
        "Snapshots": [
            {"snap-0086": {"Date": 20210911, "SnapshotState": "completed"}},
            {"snap-06ff": {"Date": 20210910, "SnapshotState": "completed"}},
            {"snap-0263": {"Date": 20210919, "SnapshotState": "completed"}},
        ],
    },
    "vol-0cc": {
        "Name": "app_server",
        "State": "in-use",
        "DataType": "Public",
        "Attachments": ["i-051"],
        "Snapshots": {},
    },
}

CodePudding user response:

Q1

If you want to use list comprehension this is the way

[volume_dict[volume_key].update({"Snapshots": snapshot_dict[volume_key] if volume_key in snapshot_dict else {}})  for volume_key, volume_value in volume_dict.items()]

A simpler approach would be

for volume_key, volume_value in volume_dict.items():
    volume_dict[volume_key]["Snapshots"] = snapshot_dict[volume_key] if volume_key in snapshot_dict else {}

Q2

That would be according to your requirement. If you want to use the original volume_dict later, better to get a copy and update.

  • Related