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

Shivin Agarwal
  • 158
  • 2
  • 16

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
  • 77,341
  • 8
  • 133
  • 139
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
  • 12,007
  • 7
  • 50
  • 88