Python: 将字典元组转换为字典

5

我该如何转换如下所示的字典元组:

({(1, 2): 3},
 {(1, 3): 5},
 {(1, 4): 5},
 {(2, 4): 5},
 {(1, 5): 10},
 {(2, 6): 9},
 {(1, 6): 9},
 {(2, 1): 2},
 {(2, 2): 3},
 {(2, 3): 5},
 {(2, 5): 10},
 {(1, 1): 2})

将其转换为较简单的形式,例如字典:

{(1, 1): 2,
 (1, 2): 3,
 (1, 3): 5,
 (1, 4): 5,
 (1, 5): 10,
 (1, 6): 9,
 (2, 1): 12,
 (2, 2): 7,
 (2, 3): 7,
 (2, 4): 3,
 (2, 5): 4,
 (2, 6): 2}

1
你尝试了什么,有什么不起作用吗? - vallentin
1
似乎您应该能够使用元组的每个元素来“更新”字典。 - mgilson
6个回答

5

虽然目前还无法使用dict合并推导式,但您可以通过链式映射来实现:

>>> from collections import ChainMap
>>> dict(ChainMap(*dicts))
{(1, 1): 2,
 (1, 2): 3,
 (1, 3): 5,
 (1, 4): 5,
 (1, 5): 10,
 (1, 6): 9,
 (2, 1): 2,
 (2, 2): 3,
 (2, 3): 5,
 (2, 4): 5,
 (2, 5): 10,
 (2, 6): 9}

注意: collections.ChainMap 是 Python 3.3 中的新功能。

实际上,它是collections.Mapping的子类,所以根据用例,您甚至可能不需要转换回普通的字典。


3

只需迭代元组并使用字典推导式重新构建“flat”字典:

a = ({(1, 2): 3},
 {(1, 3): 5},
 {(1, 4): 5},
 {(2, 4): 5},
 {(1, 5): 10},
 {(2, 6): 9},
 {(1, 6): 9},
 {(2, 1): 2},
 {(2, 2): 3},
 {(2, 3): 5},
 {(2, 5): 10},
 {(1, 1): 2})

b = {k:v for t in a for k,v in t.items()}

print(b)

结果:

{(1, 2): 3, (2, 6): 9, (2, 1): 2, (1, 1): 2, (1, 5): 10, (1, 3): 5, (1, 6): 9, (1, 4): 5, (2, 2): 3, (2, 3): 5, (2, 5): 10, (2, 4): 5}

变量名相同真有趣 :) - vav
1
你想用心灵感应编程,还是“尽可能快地打字并选择短变量名”?我会让你自己决定 :) - Jean-François Fabre

2
如果所需的字典中元素的顺序很重要,并且需要按照问题中提到的排序,请使用 collections.OrderedDict,如下所示:
# `original_list` is the variable holding the
# `list` of `dict` as mentioned in the question

required_dict = OrderedDict(
    sorted((k, v) for sub_list in original_list for k, v in sub_list.items()))

# `OrderedDict` is represented as:
#    OrderedDict([((1, 1), 2), ((1, 2), 3), ((1, 3), 5), ((1, 4), 5), ((1, 5), 10), ((1, 6), 9), ((2, 1), 2), ((2, 2), 3), ((2, 3), 5), ((2, 4), 5), ((2, 5), 10), ((2, 6), 9)])

但会返回排序过的dict,并保持与问题中所需顺序等效的顺序,如下所示:
{(1, 1): 2,
 (1, 2): 3,
 (1, 3): 5,
 (1, 4): 5,
 (1, 5): 10,
 (1, 6): 9,
 (2, 1): 12,
 (2, 2): 7,
 (2, 3): 7,
 (2, 4): 3,
 (2, 5): 4,
 (2, 6): 2}

但是,如果所需的dict中元素的顺序不重要,您可以使用简单的字典推导式来实现它,如下所示:

required_dict = {k: v for sub_list in original_list for k, v in sub_list.items()}

required_dict 的值将是:

{
    (1, 2): 3, 
    (2, 6): 9, 
    (1, 4): 5, 
    (1, 1): 2, 
    (1, 5): 10, 
    (1, 3): 5, 
    (1, 6): 9, 
    (2, 1): 2, 
    (2, 2): 3, 
    (2, 3): 5, 
    (2, 5): 10, 
    (2, 4): 5
}

注意: 由于Python中的字典本质上是无序的,因此所需字典中项目的顺序可能不同。


1
>>> a=({(1, 2): 3},
 {(1, 3): 5},
 {(1, 4): 5},
 {(2, 4): 5},
 {(1, 5): 10},
 {(2, 6): 9},
 {(1, 6): 9},
 {(2, 1): 2},
 {(2, 2): 3},
 {(2, 3): 5},
 {(2, 5): 10},
 {(1, 1): 2})
>>> {key: x[key] for x in a for key in x}
{(1, 2): 3, (2, 6): 9, (1, 4): 5, (1, 1): 2, (1, 5): 10, (1, 3): 5, (1, 6): 9, (2, 1): 2, (2, 2): 3, (2, 3): 5, (2, 5): 10, (2, 4): 5}
>>> 

0

您可以使用元组中的所有字典来更新初始字典:

values = ({(1, 2): 3},
 {(1, 3): 5},
 {(1, 4): 5},
 {(2, 4): 5},
 {(1, 5): 10},
 {(2, 6): 9},
 {(1, 6): 9},
 {(2, 1): 2},
 {(2, 2): 3},
 {(2, 3): 5},
 {(2, 5): 10},
 {(1, 1): 2})

d = dict()
reduce(lambda _, v: d.update(v), values)

-1

另一个仅适用于Python 3.5及更高版本:

>>> functools.reduce(lambda d1, d2: {**d1, **d2}, values)
{(1, 2): 3, (2, 6): 9, (2, 1): 2, (1, 1): 2, (1, 5): 10, (1, 3): 5, (1, 6): 9, (1, 4): 5, (2, 2): 3, (2, 3): 5, (2, 5): 10, (2, 4): 5}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接