0

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

2 Answers2

3

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 (i.e. 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)
Moses Koledoye
  • 74,909
  • 8
  • 119
  • 129
0

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'}]
Aaditya Ura
  • 10,695
  • 7
  • 44
  • 70