Python反转嵌套字典

时间:2013-01-28 01:14:09

标签: python nested reverse dictionary

我想采用嵌套字典并反转值 例如

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

4 个答案:

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