[ACCEPTED]-Pythonic Way to reverse nested dictionaries-list-comprehension
collections.defaultdict makes this pretty simple:
from collections import defaultdict
import pprint
data = {
'Bob' : {'item1':3, 'item2':8, 'item3':6},
'Jim' : {'item1':6, 'item4':7},
'Amy' : {'item1':6,'item2':5,'item3':9,'item4':2}
}
flipped = defaultdict(dict)
for key, val in data.items():
for subkey, subval in val.items():
flipped[subkey][key] = subval
pprint.pprint(dict(flipped))
Output:
{'item1': {'Amy': 6, 'Bob': 3, 'Jim': 6},
'item2': {'Amy': 5, 'Bob': 8},
'item3': {'Amy': 9, 'Bob': 6},
'item4': {'Amy': 2, 'Jim': 7}}
0
I totally agree that Ryan Ginstrom's answer 8 is the preferred way of doing this (for 7 all practical purposes).
But since the 6 question also explicitely asks:
Is it possible with a comprehension?
I thought 5 I'd chime in with a quick example as for 4 how to do this with a list comprehension 3 (it could be a good example for showing 2 how nested list comphrehensions can quickly 1 decrease readability).
import itertools
d = {
'Bob' : {'item1':3, 'item2':8, 'item3':6},
'Jim' : {'item1':6, 'item4':7},
'Amy' : {'item1':6,'item2':5,'item3':9,'item4':2}
}
print dict([(x, dict([(k, d[k][x]) for k,v in d.items() if x in d[k]]))
for x in set(itertools.chain(*[z for z in d.values()]))])
This is easy enough to do (as others have 8 shown), but depending on your needs you 7 should also consider that for data with 6 several pieces of information where you 5 want to extract by any criterion, a database 4 might be the best tool. The built-in sqlite3
module 3 provides a low-overhead database that may, depending 2 on what you are doing, serve you better 1 than a nested dict.
Pandas can provide another option. Assume 1 data
is the input dictionary.
import pandas as pd
output = {i:s.dropna().to_dict() for i, s in pd.DataFrame(data).T.iteritems()}
If you want just access reverse nested dictionaries, Save 2 memory if the dictionary is too large to 1 reverse.
class mdict2(dict):
def __init__(self, parent, key1):
self.parent = parent
self.key1 = key1
def __getitem__(self, key2):
return self.parent.mirror[key2][self.key1]
class mdict(dict):
def __init__(self, mirror):
self.mirror = mirror
def __getitem__(self, key):
return mdict2(self, key)
d0 = {
'Bob' : {'item1':3, 'item2':8, 'item3':6},
'Jim' : {'item1':6, 'item4':7},
'Amy' : {'item1':6,'item2':5,'item3':9,'item4':2}
}
d1 = mdict(d0)
d0['Amy']['item1'] == d1['item1']['Amy']
# True
More Related questions
We use cookies to improve the performance of the site. By staying on our site, you agree to the terms of use of cookies.