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
},
CodePudding user response:
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]}
CodePudding user response:
We could filter the data in new
until the last entry date in old
and prepend it to the list in old
:
last_date = old['price_history'][0]['date']
newest_data = [d for d in new['price_history'] if d['date'] > last_date]
old['price_history'] = newest_data old['price_history']
Then if we print old
, it now looks like:
{'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},
{'date': '3/11', 'best_buy_price': 0, 'best_sell_price': 445}]}
If your list is large, maybe it's more efficient to use collections.deque
for the same job:
from collections import deque
old['price_history'] = deque(old['price_history'])
old['price_history'].extendleft(reversed(newest_data))