简体   繁体   中英

How to convert dict in list of dicts?

{'BTC': [(None, None), (1, -0.4), (3, 0.3333333333333333), (0, 0.75), (1, None)], 'ETH': [(None, None), (0, 0.5), (0, 0.3333333333333333), (0, -0.1), (2, None)]}

in this

 [{'BTC': (None, None), 'ETH': (None, None)}, {'BTC':  (1, -0.4), 'ETH': (0, 0.5)}, {'BTC': (3, 0.3333333333333333), 'ETH': (0, -0.1)}, {'BTC': (1, None), 'ETH':  (2, None)}]

If I use lists, I can use zip function to easy convert, but how can I do this using dictionary?

Assuming you know the length of the list, then this should work:

[{z:xx[z][i] for z in xx.keys()} for i in range(5)]

Output

[{'BTC': (None, None), 'ETH': (None, None)}, {'BTC': (1, -0.4), 'ETH': (0, 0.5)}, {'BTC': (3, 0.3333333333333333), 'ETH': (0, 0.3333333333333333)}, {'BTC': (0, 0.75), 'ETH': (0, -0.1)}, {'BTC': (1, None), 'ETH': (2, None)}]

Previous answer

[{z:xx[z][i]} for z in xx.keys() for i in range(5)]

Output

[{'BTC': (None, None)}, {'BTC': (1, -0.4)}, {'BTC': (3, 0.3333333333333333)}, {'BTC': (0, 0.75)}, {'BTC': (1, None)}, {'ETH': (None, None)}, {'ETH': (0, 0.5)}, {'ETH': (0, 0.3333333333333333)}, {'ETH': (0, -0.1)}, {'ETH': (2, None)}]

Assuming all the list are of the same length, you could do:

d = {'BTC': [(None, None), (1, -0.4), (3, 0.3333333333333333), (0, 0.75), (1, None)],
     'ETH': [(None, None), (0, 0.5), (0, 0.3333333333333333), (0, -0.1), (2, None)]}

table = {}
for key, values in d.items():
    for i, value in enumerate(values):
        table.setdefault(i, {})[key] = value

result = list(table.values())
print(result)

Output

[{'BTC': (None, None), 'ETH': (None, None)}, {'BTC': (1, -0.4), 'ETH': (0, 0.5)}, {'BTC': (3, 0.3333333333333333), 'ETH': (0, 0.3333333333333333)}, {'BTC': (0, 0.75), 'ETH': (0, -0.1)}, {'BTC': (1, None), 'ETH': (2, None)}]

The idea is to create a dictionary where the key are indices and the values are the expected dictionaries.

My guess is that it has to do with how the dict and list are hashed. Dict has key values, and orders itself how it sees fit, lists don't. You're also using tuples in here too though, so that might affect it. Is there a reason you're structuring it this way? Seems like it could be more efficiently done with just lists and dicts.

Either way, you'd just be a lot better off using pandas. Especially if you're using it for crypto-currency, or any other financial data. It'll do a lot for you.

Let's say tickers is a list of cryptocurrency coins. and then we have a dict of the financial data using the range(len(tickers)) of tickers as the key.

import pandas as pd

tickers=['BTC','ETC','ETH','LTC','XRP', etc.]

financial_data={}
for i in range(len(tickers)):
    financial_data[i]= get_finince_data(tickers[i])
                        #^this isn't an actual function. just an example 
                        #to represent whatever you're using to pull data
financial_data= pd.DataFrame(financial_data)

or, if you really like the structure that you're using now.

d = {'BTC': [(None, None), (1, -0.4), (3, 0.3333333333333333), (0, 0.75), (1, None)],
 'ETH': [(None, None), (0, 0.5), (0, 0.3333333333333333), (0, -0.1), (2, None)]}

d=pd.DataFrame(d)

Another solution

result = []
for key, value in raw.items():
    for index, item in enumerate(value):
        if len(result) <= index:
            result.append({key: item})
        else:
            result[index][key] = item

result

You can use a list comprehension after calculating the number of list elements:

d = {'BTC': [(None, None), (1, -0.4), (3, 0.3333333333333333), (0, 0.75), (1, None)],
     'ETH': [(None, None), (0, 0.5), (0, 0.3333333333333333), (0, -0.1), (2, None)]}

n = len(next(iter(d_input.values())))
res = [{k: v[i] for k, v in d_input.items()} for i in range(n)]

If you are able to use 3rd party Pandas, perhaps the easiest way is to convert to a dataframe and then use to_dict :

import pandas as pd

res = pd.DataFrame(d_input).to_dict('records')

print(res)

[{'BTC': (None, None), 'ETH': (None, None)},
 {'BTC': (1, -0.4), 'ETH': (0, 0.5)},
 {'BTC': (3, 0.3333333333333333), 'ETH': (0, 0.3333333333333333)},
 {'BTC': (0, 0.75), 'ETH': (0, -0.1)},
 {'BTC': (1, None), 'ETH': (2, None)}]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM