I'm trying to merge three dictionaries, which all have the same keys, and either lists of values, or single values.
one={'a': [1, 2], 'c': [5, 6], 'b': [3, 4]} two={'a': [2.4, 3.4], 'c': [5.6, 7.6], 'b': [3.5, 4.5]} three={'a': 1.2, 'c': 3.4, 'b': 2.3}
What I need is for all the items in the values to be added to one list.
result={'a': [1, 2, 2.4, 3.4, 1.2], 'c': [5, 6, 5.6, 7.6, 2.3], 'b': [3, 4, 3.5, 4.5, 3.4]}
I have tried several things, but most put the values into nested lists. E.g.
out=dict((k, [one[k], two.get(k), three.get(k)]) for k in one) {'a': [[1, 2], [2.4, 3.4], 1.2], 'c': [[5, 6], [5.6, 7.6], 3.4], 'b': [[3, 4], [3.5, 4.5], 2.3]}
I tried updating it by looping through the values:
out.update((k, [x for x in v]) for k,v in out.iteritems())
but the results was exactly the same. I have tried to simply add the lists, but because the third dictionary has only a float, I couldn't do it.
check=dict((k, [one[k]+two[k]+three[k]]) for k in one)
So I tried to first add the lists in values of one and two, and then append the value of three. Adding the lists worked well, but then when I tried to append the float from the third dictionary, suddenly the whole value went to 'None'
check=dict((k, [one[k]+two[k]]) for k in one) {'a': [[1, 2, 2.4, 3.4]], 'c': [[5, 6, 5.6, 7.6]], 'b': [[3, 4, 3.5, 4.5]]} new=dict((k, v.append(three[k])) for k,v in check.items()) {'a': None, 'c': None, 'b': None}
To merge multiple dictionaries, the most Pythonic way is to use dictionary comprehension {k:v for x in l for k,v in x. items()} to first iterate over all dictionaries in the list l and then iterate over all (key, value) pairs in each dictionary.
Python 3.9 has introduced the merge operator (|) in the dict class. Using the merge operator, we can combine dictionaries in a single line of code. We can also merge the dictionaries in-place by using the update operator (|=).
In python, we can use the + operator to merge the contents of two lists into a new list. For example, We can use + operator to merge two lists i.e. It returned a new concatenated lists, which contains the contents of both list_1 and list_2.
As a one-liner, with a dictionary comprehension:
new = {key: value + two[key] + [three[key]] for key, value in one.iteritems()}
This creates new lists, concatenating the list from one
with the corresponding list from two
, putting the single value in three
into a temporary list to make concatenating easier.
Or with a for
loop updating one
in-place:
for key, value in one.iteritems(): value.extend(two[key]) value.append(three[key])
This uses list.extend()
to update original list in-place with the list from two
, and list.append()
to add the single value from three
.
Where you went wrong:
your first attempt creates a new list with the values from one
, two
and three
nested within rather than concatenating the existing lists. Your attempt to clean that up just copied those nested lists across.
Your second attempt didn't work because the value in three
is not a list so could not be concatenated. I created a new list just for that one value.
Your last attempt should not have used list.append()
in a generator expression, because you store the return value of that method, which is always None
(its change is stored in v
directly and the list doesn't need returning again).
Demo of the first approach:
>>> one={'a': [1, 2], 'c': [5, 6], 'b': [3, 4]} >>> two={'a': [2.4, 3.4], 'c': [5.6, 7.6], 'b': [3.5, 4.5]} >>> three={'a': 1.2, 'c': 3.4, 'b': 2.3} >>> {key: value + two[key] + [three[key]] for key, value in one.iteritems()} {'a': [1, 2, 2.4, 3.4, 1.2], 'c': [5, 6, 5.6, 7.6, 3.4], 'b': [3, 4, 3.5, 4.5, 2.3]}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With