-2

I'm trying to create a junction of the dicts bellow:

buy_dict = {'Coin1': [{'buy_price': 105, 'id_buy':2 },{'buy_price': 100, 'id_buy':1 }], 'Coin2': [{'buy_price': 1200, 'id_buy':2 },{'buy_price': 1100, 'id_buy':1 }]}

sell_dict = {'Coin1': [{'sell_price': 106, 'id_sell':1 }, {'sell_price': 110, 'id_sell':2 }], 'Coin2': [{'sell_price': 1250, 'id_sell':1 },{'sell_price': 1350, 'id_sell':2 }]}

On the buy_dict I have a dict with buy prices and its ids, grouped by Coin. The same model on the sell_dict. What I need to do is create a third dict by joining the data from two dicts adobe, so the first record of the new dict would be the first record of the dictA plus the first record of the dictB. Below is how it should look:

DictC = {'Coin1': [{'buy_price': 105, 'id_buy':2, 'sell_price': 106, 'id_sell':1}, {'buy_price': 100, 'id_buy':1, 'sell_price': 110, 'id_sell':2}], 'Coin2': [{'buy_price': 1200,'id_buy':2, 'sell_price': 1250,'id_sell':1}, {'buy_price': 1100, 'id_buy':1,'sell_price': 1350,'id_sell':2}]}

In short, the records of DictC would be a junction of the highest buying price and the lowest selling prices. No ordering is required because buy_dict and sell_dict are already ordered.

Thanks!!

Joe Iddon
  • 20,101
  • 7
  • 33
  • 54

3 Answers3

1

This trick is that you are combining two dictionaries and also iterating through array in order. The difference from mine an joes answer is that mine is tolerant of a coin only existing in one dict and a different number of sells and buys in each list.

  from collections import defaultdict
  from itertools import zip_longest

  DictC = defaultdict(list)
  for coin in (buy_dict.keys() | sell_dict.keys()):
      for buy_item, sell_item in zip_longest(buy_dict.get(coin, []), sell_dict.get(coin, []), fillvalue={}):
          DictC[coin].append({**buy_item, **sell_item})

For python2.7 replace DictC[coin].append({**buy_item, **sell_item}) with

temp = buy_item.copy()
temp.update(sell_item)
DictC[coin].append(temp)

and buy_dict.keys() | sell_dict.keys() with set(buy_dict.keys() + sell_dict.keys()) and zip_longest with izip_longest

costrouc
  • 3,045
  • 2
  • 19
  • 23
0

The simplest method I found was:

dictD = {}
for coin in sell_dict:
    coinList = []
    for things in zip(sell_dict[coin], buy_dict[coin]):
        joinedDict = {}
        for d in things:
            joinedDict.update(d)
        coinList.append(joinedDict)
    dictD[coin] = coinList

I assume here that the keys of sell_dict and buy_dict are identical. Other than doing the obvious for loops, there isn't anything special other than the use of zip to get the lists aligned the way you want.

Brian Fett
  • 11
  • 3
-1

You can do this in a one-line dictionary-comprehension:

{k: [{**buy_dict[k][i], **sell_dict[k][i]} for i in range(len(buy_dict[k]))] for k in buy_dict}

which gives your desired output of:

{'Coin1': [{'id_sell': 1, 'buy_price': 105, 'id_buy': 2, 'sell_price': 106}, {'id_sell': 2, 'buy_price': 100, 'id_buy': 1, 'sell_price': 110}], 'Coin2': [{'id_sell': 1, 'buy_price': 1200, 'id_buy': 2, 'sell_price': 1250}, {'id_sell': 2, 'buy_price': 1100, 'id_buy': 1, 'sell_price': 1350}]}

why?

Well we want to iterate through each key in buy_dict, so that is our outer-most loop. Then inside this, we want to set this key to a value which is a list. This is done with the syntax: {k: [...] for k in buy_dict}.

And what goes in this list? Well since the lists in the original dictionaries are already ordered correctly, we can just unpack them in order into their own new one.

So to do this, we iterate through the different indexes in the buy_dict[k] list and then use the unpacking technique seen here to form a new dictionary.


Note that of course the outputted dictionary isn't identical in terms of order to yours as dictionaries have no order; they are merely a set of key:value pairs

Joe Iddon
  • 20,101
  • 7
  • 33
  • 54