我想采用嵌套字典并反转值 例如
input = { "a" : { "x": 2, "y": 3 },
"b" : { "x": 5, "z": 7 } }
output = {'y': {'a': 3},
'x': {'a': 2, 'b': 5},
'z': {'b': 7} }
我有什么:
def reverse_nest_dicts(nested_dict):
reverse_nest_dict = {}
for k, v in nested_dict:
for k2, v2 in nested_dict.values():
reverse_nest_dict[k2][k] = v2
return reverse_nest_dict
答案 0 :(得分:2)
for k2, v2 in nested_dict.values():
应该是
for k2, v2 in v.items():
(另请注意,如果您使用的是Python 2.x,使用.iteritems()
代替.items()
可能会更有效。)
您还需要确保初始化子词典 - 您可以使用defaultdict
...
from collections import defaultdict
reverse_nest_dict = defaultdict(dict)
...或使用setdefault
:
reverse_nest_dict.setdefault(k2, {})[k] = v2
答案 1 :(得分:1)
您的功能有三种不同的错误。以下是您的目标:
def reverse_nest_dicts(nested_dict):
reverse_nest_dict = {}
for k, v in nested_dict.iteritems():
for k2, v2 in v.iteritems():
try:
reverse_nest_dict[k2][k] = v2
except KeyError:
reverse_nest_dict[k2] = { k : v2 }
return reverse_nest_dict
错误是:
第一个for循环:使用字典作为循环序列只会导致键,你想要(键,值)所以需要使用items()或iteritems()
第二个for循环:循环序列应该是嵌套字典,而不是外部字典
在尝试访问内部词典之前,需要将reverse_nest_dict值初始化。
答案 2 :(得分:0)
dictionary items() and setdefault() methods做了这类问题的简短工作:
>>> input = { "a" : { "x": 2, "y": 3 },
"b" : { "x": 5, "z": 7 } }
>>> result = {}
>>> for k1, subdict in input.items():
for k2, v in subdict.items():
result.setdefault(k2, {})[k1] = v
>>> result
{'y': {'a': 3}, 'x': {'a': 2, 'b': 5}, 'z': {'b': 7}}
在Python 2中,您可以使用 iteritems()而不是 items()来获得较小的速度提升。
同样,使用 collections.defaultdict(dict)可能比使用 setdefault 快一点。当然,这将返回defaultdict而不是你问题中指定的dict。
答案 3 :(得分:0)
如果词典太大,请检查https://stackoverflow.com/a/47151034/676214
如果您只想访问反向嵌套词典, 如果字典太大而无法反转,请节省内存。
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