简体   繁体   中英

Python dictionary manipulation into list of dictionary

I m fairly new to python and having a hard time solving this problem, I have a dictionary in format:

{'tag1_batch1_st': OrderedDict([(0.0, '59.83163071'), (1.0, '18.94903946'), (2.0, '48.38692856'), (3.0, '0.05321884'), (4.0, '4.20608902'), (5.0, '01.66112137'), (6.0, '0.59775162'), (7.0, '37.17335892'), (8.0, '0.78234863'), (9.0, '1.67506027')]), 'tag_batch_st ': OrderedDict([(0.0, '58.83163071'), (1.0, '48.94903946'), (2.0, '38.38692856'), (3.0, '45.05321884'), (4.0, '40.20608902'), (5.0, '38.66112137'), (6.0, '37.59775162'), (7.0, '37.17335892'), (8.0, '36.78234863'), (9.0, '36.67506027')])}

I want to convert it into a list like this:

[{'tag1_batch1_st': '59.83163071', 'num': 0.0, 'tag_batch_st': '58.83163071'}, ...... ]

I know, I can use for loop and iterate over the dictionary and create the list, but any approach which would require less iterations and methods like groupby() would be helpful.

Thanks

There's no approach that'll give a complexity less than O(n) - n is the number of key, value pairs in the OrderedDict. You have iterate on every pair, so no such thing as less iterations.

You can iterate on the dict values' key-value pairs (ie key-value pairs of OrderDict) simultaneously by zipping them and then build new dicts using the new pair and adding a new key entry:

lst = []
for (num, st1), (_, st2) in zip(*map(dict.items, dct.values())):
   d = dict(zip(dct.keys(), (st1, st2)))
   d['num'] = num
   lst.append(d)

[{'tag1_batch1_st': '59.83163071', 'tag_batch_st ': '58.83163071', 'num': 0.0}, 
 {'tag1_batch1_st': '18.94903946', 'tag_batch_st ': '48.94903946', 'num': 1.0}, 
 ...
]

In case you have more keys in the dictionary, you can use map(zip, ...) to collect all the values from the ordered dicts in a tuple, and the zip the tuple with the parent dictionary keys:

for (num, _), sts in map(zip, *map(dict.items, dct.values())):
   d = dict(zip(dct.keys(), sts))
   d['num'] = num
   lst.append(d)

You can use default dict and lambda :

Two line solution :

from collections import OrderedDict,defaultdict
a={'tag1_batch1_st': OrderedDict([(0.0, '59.83163071'), (1.0, '18.94903946'), (2.0, '48.38692856'), (3.0, '0.05321884'), (4.0, '4.20608902'), (5.0, '01.66112137'), (6.0, '0.59775162'), (7.0, '37.17335892'), (8.0, '0.78234863'), (9.0, '1.67506027')]), 'tag_batch_st ': OrderedDict([(0.0, '58.83163071'), (1.0, '48.94903946'), (2.0, '38.38692856'), (3.0, '45.05321884'), (4.0, '40.20608902'), (5.0, '38.66112137'), (6.0, '37.59775162'), (7.0, '37.17335892'), (8.0, '36.78234863'), (9.0, '36.67506027')])}

default_dict = defaultdict(list)
list(map(lambda x:[default_dict[key].append(value) for key,value in x.items()],a.values()))


print([{'tag1_batch1_st':value[0],'tag_batch1_st':value[1],'num':key} for key,value in default_dict.items()])

output:

[{'num': 0.0, 'tag_batch1_st': '59.83163071', 'tag1_batch1_st': '58.83163071'}, {'num': 1.0, 'tag_batch1_st': '18.94903946', 'tag1_batch1_st': '48.94903946'}, {'num': 2.0, 'tag_batch1_st': '48.38692856', 'tag1_batch1_st': '38.38692856'}, {'num': 3.0, 'tag_batch1_st': '0.05321884', 'tag1_batch1_st': '45.05321884'}, {'num': 4.0, 'tag_batch1_st': '4.20608902', 'tag1_batch1_st': '40.20608902'}, {'num': 5.0, 'tag_batch1_st': '01.66112137', 'tag1_batch1_st': '38.66112137'}, {'num': 6.0, 'tag_batch1_st': '0.59775162', 'tag1_batch1_st': '37.59775162'}, {'num': 7.0, 'tag_batch1_st': '37.17335892', 'tag1_batch1_st': '37.17335892'}, {'num': 8.0, 'tag_batch1_st': '0.78234863', 'tag1_batch1_st': '36.78234863'}, {'num': 9.0, 'tag_batch1_st': '1.67506027', 'tag1_batch1_st': '36.67506027'}]

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