'Combining dictionaries that contain a list of objects in Python

I'm trying to combine two dictionaries (actually JSON). Essentially, the API I'm using only give the three newest values, so I want to combine those with the data I already have to create a longer history.

Here is what I tried:

old = {
    "price_history": [
    {
        "date": "3/13",
        "best_buy_price": 0,
        "best_sell_price": 742
    },
    {
        "date": "3/12",
        "best_buy_price": 0,
        "best_sell_price": 463
    },
    {
        "date": "3/11",
        "best_buy_price": 0,
        "best_sell_price": 445
    },
]}

new = {
    "price_history": [
    {
        "date": "3/14",
        "best_buy_price": 0,
        "best_sell_price": 1000
    },
    {
        "date": "3/13",
        "best_buy_price": 0,
        "best_sell_price": 742
    },
    {
        "date": "3/12",
        "best_buy_price": 0,
        "best_sell_price": 463
    },
]}

price_history = {**old, **new}

However, the output of this ends up being:

    {
        "date": "3/14",
        "best_buy_price": 0,
        "best_sell_price": 1000
    },
    {
        "date": "3/13",
        "best_buy_price": 0,
        "best_sell_price": 742
    },
    {
        "date": "3/12",
        "best_buy_price": 0,
        "best_sell_price": 463
    },

I'm trying to get something like this:

    {
        "date": "3/14",
        "best_buy_price": 0,
        "best_sell_price": 1000
    },
    {
        "date": "3/13",
        "best_buy_price": 0,
        "best_sell_price": 742
    },
    {
        "date": "3/12",
        "best_buy_price": 0,
        "best_sell_price": 463
    },
    {
        "date": "3/11",
        "best_buy_price": 0,
        "best_sell_price": 445
    },


Solution 1:[1]

You can try something like this:

from datetime import datetime
def extract(v):
    return (v["date"], v["best_buy_price"], v["best_sell_price"])
temp = sorted(set(extract(v) for v in new["price_history"]) | set(extract(v) for v in old["price_history"]), key=lambda x: datetime.strptime(x[0], "%m/%d"), reverse=True)
price_history = {"price_history": [{"date": v[0], "best_buy_price": v[1], "best_sell_price": v[2]} for v in temp]}

More generally (i.e. more than just 3 keys in the object), you can do something like this (assuming new["price_history"] is non-empty)):

from datetime import datetime
keys = sorted(new["price_history"][0])
date_index = keys.index("date")
def extract(val):
    return tuple(val[k] for k in keys)
temp = sorted(set(extract(v) for v in new["price_history"]) | set(extract(v) for v in old["price_history"]), key=lambda x: datetime.strptime(x[date_index], "%m/%d"), reverse=True)
price_history = {"price_history": [{keys[i]: v[i] for i in range(len(keys))} for v in temp]}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1