使用理解,使用嵌套元组作为键从dict创建嵌套dict

时间:2016-10-19 11:40:58

标签: python dictionary nested tuples list-comprehension

今年早些时候我在这个问题上得到了一个非常有用的答案,但我可以使用熊猫。现在我必须使用纯Python。

有这样的字典:

inp = {((0, 0), 0): -99.94360791266038,
       ((0, 0), 1): -1.1111111111107184,
       ((1, 0), 0): -1.111111111107987,
       ((1, 0), 1): -1.1111111111079839,
       ((1, 0), 3): -1.111111111108079}

现在我想在这样的嵌套字典中转换它:

out = {(0,0): {0: -99.94360791266038, 1: -1.1111111111107184},
       (1,0): {0: -1.111111111107987,
               1: -1.1111111111079839,
               3: -1.111111111108079}

如何通过优雅的词汇理解来实现这一目标?我无法理解它。

2 个答案:

答案 0 :(得分:3)

我不是用dict comprenhesion这样做的。只需使用一个简单的循环:

out = {}
for key, value in inp.items():
    k1, k2 = key
    out.setdefault(k1, {})[k2] = value

演示:

>>> inp = {((0, 0), 0): -99.94360791266038,
...        ((0, 0), 1): -1.1111111111107184,
...        ((1, 0), 0): -1.111111111107987,
...        ((1, 0), 1): -1.1111111111079839,
...        ((1, 0), 3): -1.111111111108079}
>>> out = {}
>>> for key, value in inp.items():
...     k1, k2 = key
...     out.setdefault(k1, {})[k2] = value
...
>>> from pprint import pprint
>>> pprint(out)
{(0, 0): {0: -99.94360791266038, 1: -1.1111111111107184},
 (1, 0): {0: -1.111111111107987,
          1: -1.1111111111079839,
          3: -1.111111111108079}}

也可以使用dict理解,但是您需要对键进行排序并使用itertools.groupby()对第一个元组元素上的键进行分组。排序需要O(NlogN)时间,并且像上面这样的简单循环很容易打败。

仍然,为了完整起见:

from itertools import groupby
out = {g: {k[1]: v for k, v in items} 
       for g, items in groupby(sorted(inp.items()), key=lambda kv: kv[0][0])}

答案 1 :(得分:1)

天真的解决方案:

my_dict = {
            ((0, 0), 0): -99.94360791266038,
            ((0, 0), 1): -1.1111111111107184,
            ((1, 0), 0): -1.111111111107987,
            ((1, 0), 1): -1.1111111111079839,
            ((1, 0), 3): -1.111111111108079
        }

def get_formatted_dict(my_dict):
    formatted_dict = {}
    for k, v in my_dict.items():
        index_1, index_2 = k
        if index_1 not in formatted_dict:
            formatted_dict[index_1] = {}
        formatted_dict[index_1][index_2] = v
    return formatted_dict

print(get_formatted_dict(my_dict))

输出:

{(1, 0): {0: -1.111111111107987, 1: -1.1111111111079839, 3: -1.111111111108079}, (0, 0): {0: -99.94360791266038, 1: -1.1111111111107184}}