Home > Software engineering >  subtract two list of dict in python
subtract two list of dict in python

Time:01-09

I have two list like below and i want to subtract second one from first one, but i failed with solutions in the other questions.

First list

My first list is somthing look like below:

[
    {
        "app_name": [
            {
                "date": "2023.01.04",
                "platform": "web"
            },
            {
                "date": "2022.12.13",
                "platform": "web"
            }
        ]
    },
    {
        "another_app_name": [
            {
                "date": "2022.12.25",
                "platform": "windows"
            },
            {
                "date": "2022.12.31",
                "platform": "ios"
            }
        ]
    }
]

Second list

My Second list is somthing look like below:

[
    {
        "app_name": [
            {
                "date": "2023.01.04",
                "platform": "web"
            }
        ]
    },
    {
        "another_app_name": [
            {
                "date": "2022.12.31",
                "platform": "ios"
            }
        ]
    }
]

Resulte must be like:

[
    {
        "app_name": [
            {
                "date": "2022.12.13",
                "platform": "web"
            }
        ]
    },
    {
        "another_app_name": [
            {
                "date": "2022.12.25",
                "platform": "windows"
            }
        ]
    }
]

there is my solution:

for f, b in zip(all_pcap, failed_pcap):
        res = {key: f[key] - b.get(key, 0) for key in f}

CodePudding user response:

If the dictionaries in your lists only ever contain a single {key: value} pair, then a better data structure for the data would be something like this:

apps = {
    "app_name": [{"date": "2023.01.04", "platform": "web"}, {"date": "2022.12.13", "platform": "web"}],
    "another_app_name": [{"date": "2022.12.25", "platform": "windows"}, {"date": "2022.12.31", "platform": "ios"}],
}

Assuming that that is the case, and the app names are unique in each dictionary, then it makes the problem a bit easier.

Using the values you provided:

a = [
    {"app_name": [{"date": "2023.01.04", "platform": "web"}, {"date": "2022.12.13", "platform": "web"}]},
    {"another_app_name": [{"date": "2022.12.25", "platform": "windows"}, {"date": "2022.12.31", "platform": "ios"}]}
]

b = [
    {"app_name": [{"date": "2023.01.04", "platform": "web"}]},
    {"another_app_name": [{"date": "2022.12.31", "platform": "ios"}]}
]

expected = [
    {"app_name": [{"date": "2022.12.13", "platform": "web"}]},
    {"another_app_name": [{"date": "2022.12.25", "platform": "windows"}]}
]

We can define a function that transforms the data into a format that is easier to work with, perform the removals, and then transform it back into the currently expected format:

def remove_app_entries(a, b):
    a_transformed = {k: v for row in a for k, v in row.items()}
    b_transformed = {k: v for row in b for k, v in row.items()}

    results = {}

    for app, data in a_transformed.items():
        to_remove = b_transformed.get(app)
        if not to_remove:
            results[app] = data
        else:
            results[app] = [row for row in data if row not in to_remove]

    return [{app: data} for app, data in results.items()]

This results in data that matches the specified expected data:

>>> remove_app_entries(a, b) == expected
True

If the data was already in the format I suggested, then you would skip the a_transformed / b_transformed steps and use a and b directly. If it also works for the return value, then results could be simply returned at the end instead of transforming it into a list.

  • Related