我有以下格式的字典
dict = {
"a" : {"a1" : 1},
"b" : {"a2" : 1, "a3" : 2},
"c" : {"a2" : 3, "a4" : 3}
}
我需要以下形式的反向索引字典:
inverseDict = {
"a1" : {"a" : 1},
"a2" : {"b" : 1, "c" : 3},
"a3" : {"b" : 2},
"a4" : {"c" : 3}
}
基本上
inverseDict = {dict.value.key : { dict.key : dict.value.value}}
所以从本质上讲,我需要将值的键作为键,并将键作为值的键,同时将重复的新键等的结果加入
我试图做
ks = dict.keys()
vals = dict.values()
ks2 = vals.keys()
vals2 = vals.values()
如果这有道理
但是我遇到了错误
'dict_values' object has no attribute 'keys'
据我了解,这是因为dict.values().keys().items()返回“视图”而不是实际元素本身,但我不知道要解决这个问题很热。
还有一种更有效的解决方案,我应该考虑,因为我的实际dict非常大(〜10k键),并且所得到的逆dict也很大(> 3k键)
答案 0 :(得分:6)
使用collections.defaultdict(dict)
和双循环非常简单:
d = {
"a" : {"a1" : 1},
"b" : {"a2" : 1, "a3" : 2},
"c" : {"a2" : 3, "a4" : 3},
}
import collections
inverted = collections.defaultdict(dict)
for key,subd in d.items():
for k,v in subd.items(): # no inspiration for key/value names...
inverted[k][key] = v
inverted
是
{'a1': {'a': 1},
'a2': {'b': 1, 'c': 3},
'a3': {'b': 2},
'a4': {'c': 3}}
使用defaultdict
可以避免测试条目是否已经存在,如果不存在则创建字典值。因此,只需按预期顺序轻松地添加键/值即可。
请注意,那些需要将物品分解为多个对象的问题几乎无法使用理解力解决。
答案 1 :(得分:1)
另一种解决方案没有标准库...但是Jean-Francois Fabre的答案更为简洁,可能更易于模块化。如有疑问,请使用标准库。
OriginalDict = ... (Original dict items)
InvertedDict = {}
for k, v in OriginalDict.items():
for k_, v_ in v.items():
if InvertedDict.get(k_) is None:
InvertedDict[k_] = {}
InvertedDict[k_][k] = v_
答案 2 :(得分:1)
您可以使用setdefault:
d = {
'a': {'a1': 1},
'b': {'a2': 1, 'a3': 2},
'c': {'a2': 3, 'a4': 3}
}
result = {}
for ok, vs in d.items():
for ik, v in vs.items():
result.setdefault(ik, {})[ok] = v
print(result)
输出
{'a4': {'c': 3}, 'a1': {'a': 1}, 'a2': {'c': 3, 'b': 1}, 'a3': {'b': 2}}
函数setdefault
与defaultdict
的用法类似。