Reputation: 2843
I am trying to group these fields together by trailing numbers in the keys in order to turn this dictionary:
dict = {
'location_1': 'Living Room', 'status_1': True, 'information_1': 'good',
'location_2': 'Dining Room', 'status_2': True, 'information_2': 'good',
'location_3': 'Kitchen', 'status_3': True, 'information_3': 'good'
}
Into this:
new = {
'Living Room': {'status': True, 'information': 'good'},
'Dining Room': {'status': True, 'information': 'good'},
'Kitchen': {'status': True, 'information': 'good'}
}
How can I accomplish this?
Here was my attempt, I can't seem to get the logic right:
json = dict()
counter = 0
so_far = {}
for key, value in cleaned_data.items():
v = key.split('_')[0]
print(v)
so_far[key.split('_')[0]] = value
print(so_far)
if counter != 0 and counter % 3 == 0:
# I don't know where status or information are yet...
json[so_far['location']] = {
'status': so_far['status'],
'information': so_far['information']
}
# reset
so_far = dict()
counter += 1
print(json)
Upvotes: 2
Views: 85
Reputation: 92854
Short approach with old-good collections.defaultdict
object:
import pprint
from collections import defaultdict
d = {
'location_1': 'Living Room', 'status_1': True, 'information_1': 'good',
'location_2': 'Dining Room', 'status_2': True, 'information_2': 'good',
'location_3': 'Kitchen', 'status_3': True, 'information_3': 'good'
}
groups = defaultdict(dict)
for k,v in d.items():
name, idx = k.split('_')
groups[idx][name] = v
res = {v.pop('location'): v for v in groups.values()}
pprint.pprint(res)
The output:
{'Dining Room': {'information': 'good', 'status': True},
'Kitchen': {'information': 'good', 'status': True},
'Living Room': {'information': 'good', 'status': True}}
Upvotes: 2
Reputation: 71451
You can use itertools.groupby
:
from itertools import groupby
d = {'location_1': 'Living Room', 'status_1': True, 'information_1': 'good', 'location_2': 'Dining Room', 'status_2': True, 'information_2': 'good', 'location_3': 'Kitchen', 'status_3': True, 'information_3': 'good'}
new_d = [(a.split('_'), b) for a, b in d.items()]
new_data = [{c:d for [c, _], d in b} for _, b in groupby(sorted(new_d, key=lambda x:x[0][1]), key=lambda x:x[0][1])]
result = {i['location']:{'status':i['status'], 'information':i['information']} for i in new_data}
Output:
{'Living Room': {'status': True, 'information': 'good'}, 'Dining Room': {'status': True, 'information': 'good'}, 'Kitchen': {'status': True, 'information': 'good'}}
Edit: if the different information values in the final output are intentional, you can use zip
:
info = ['good', 'awesome', 'yay']
result = {i['location']:{'status':i['status'], 'information':a} for i, a in zip(new_data, info)}
Output:
{'Living Room': {'status': True, 'information': 'good'}, 'Dining Room': {'status': True, 'information': 'awesome'}, 'Kitchen': {'status': True, 'information': 'yay'}}
Upvotes: 4