在python中,如何反转2D词典?

时间:2018-11-05 20:14:17

标签: python python-3.x dictionary

我有以下格式的字典

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键)

3 个答案:

答案 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}}

函数setdefaultdefaultdict的用法类似。