I have a nested dictionary of people and item ratings, with people as the key. people may or may not share items. Example:
{
\'Bob\' : {\'item1\':3, \'item2
This is easy enough to do (as others have shown), but depending on your needs you should also consider that for data with several pieces of information where you want to extract by any criterion, a database might be the best tool. The built-in sqlite3
module provides a low-overhead database that may, depending on what you are doing, serve you better than a nested dict.
I totally agree that Ryan Ginstrom's answer is the preferred way of doing this (for all practical purposes).
But since the question also explicitely asks:
Is it possible with a comprehension?
I thought I'd chime in with a quick example as for how to do this with a list comprehension (it could be a good example for showing how nested list comphrehensions can quickly 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()]))])
If you want just access reverse nested dictionaries, Save memory if the dictionary is too large to 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
Pandas can provide another option. Assume data
is the input dictionary.
import pandas as pd
output = {i:s.dropna().to_dict() for i, s in pd.DataFrame(data).T.iteritems()}
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}}