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}
source to share
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}
source to share
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.
source to share
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.
source to share
>>> 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}
>>>
source to share
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)
source to share