Python: tuple of dictionary for dictionary

How can I convert a tuple of dictionaries like the example below:

({(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})

      

in a simpler form like a dictionary:

{(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}

      

+3


source to share


6 answers


just iterate over the tuples and rebuild the dictionary "flat" using dictionary comprehension:

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)

      



result:

{(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}

      

+3


source


If the order of the items in the desired dict

is relevant
and necessary for sorting as stated in the question, use collections.OrderedDict

like:

# `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)])

      

but returns a sorted dict

, order-maintaining equivalent to the one asked in the question, like:

{(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}

      

But , if the order of the items in the desired dict

doesn't matter
, you can use a simple understanding of concepts to achieve it like:



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

      

where the value required_dict

would be:

{
    (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
}

      

Note: The order of the elements in the desired dict is different because dictionaries in Python are inherently unordered.

+2


source


You can't use merge comprehension (yet), but you can navigate through the netmap :

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

      

Note: collections.ChainMap

is new in Python 3.3.

It is actually a subclass collections.Mapping

, so depending on which variation you are using, you may not even need to convert back to a simple dict.

+2


source


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

      

+1


source


You can update the original dict with all the formatting from the tuple:

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)

      

0


source


Another one, exclusive to Python 3.5 and newer:

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

      

-1


source







All Articles