26

I have the following two toy dicts

d1 = {
 'a': [2,4,5,6,8,10],
 'b': [1,2,5,6,9,12],
 'c': [0,4,5,8,10,21]
 }
d2 = {
 'a': [12,15],
 'b': [14,16],
 'c': [23,35]
  }

and I would like get a unique dictionary where I stack the second dictionary values after the first ones, within the same square brackets.

I tried the following code

d_comb = {key:[d1[key], d2[key]] for key in d1}

but the output I obtain has two lists within a list for each key, i.e.

{'a': [[2, 4, 5, 6, 8, 10], [12, 15]],
 'b': [[1, 2, 5, 6, 9, 12], [14, 16]],
 'c': [[0, 4, 5, 8, 10, 21], [23, 35]]}

whereas I would like to obtain

{'a': [2, 4, 5, 6, 8, 10, 12, 15],
 'b': [1, 2, 5, 6, 9, 12, 14, 16],
 'c': [0, 4, 5, 8, 10, 21, 23, 35]}

How can I do that with a line or two of code?

yatu
  • 86,083
  • 12
  • 84
  • 139
Ric S
  • 9,073
  • 3
  • 25
  • 51
  • Are we sure that both `d1` and `d2` have same set of keys? – cph_sto Jan 09 '19 at 12:39
  • In this example and according to my present needs, yes. Of course I'm sure that with different sets of keys in the two dictionaries the code will be different. – Ric S Jan 09 '19 at 13:03

5 Answers5

33

You almost had it, instead use + to append both lists:

{key: d1[key] + d2[key] for key in d1}

{'a': [2, 4, 5, 6, 8, 10, 12, 15],
 'b': [1, 2, 5, 6, 9, 12, 14, 16],
 'c': [0, 4, 5, 8, 10, 21, 23, 35]}
yatu
  • 86,083
  • 12
  • 84
  • 139
  • 2
    Damn, it was the plus sign, not the comma.. I knew it was easy but it didn't come to mind! Thanks – Ric S Jan 09 '19 at 11:38
14

if not all the keys from d2 are in d1, then the simplest thing is using set union and dict.get:

combined_keys = d1.keys() | d2.keys()
d_comb = {key: d1.get(key, []) + d2.get(key, []) for key in combined_keys}
Maarten Fabré
  • 6,938
  • 1
  • 17
  • 36
9

You could use extended iterable unpacking:

d1 = {
 'a': [2,4,5,6,8,10],
 'b': [1,2,5,6,9,12],
 'c': [0,4,5,8,10,21]
 }
d2 = {
 'a': [12,15],
 'b': [14,16],
 'c': [23,35]
  }

d_comb = {key:[*d1[key], *d2[key]] for key in d1}

print(d_comb)

Output

{'c': [0, 4, 5, 8, 10, 21, 23, 35], 'b': [1, 2, 5, 6, 9, 12, 14, 16], 'a': [2, 4, 5, 6, 8, 10, 12, 15]}
Dani Mesejo
  • 61,499
  • 6
  • 49
  • 76
5

You can use itertools.chain to efficiently construct a single list from input lists:

from itertools import chain
d_comb = {key: list(chain(d1[key], d2[key])) for key in d1}

For the more general case covering an arbitrary number of dictionaries and keys which are not equal across dictionaries, see Merging dictionary value lists in python.

jpp
  • 159,742
  • 34
  • 281
  • 339
4

The code will work irrespective of whether d1 or d2 have the same set of keys. I have added a key 'e' in d1 and 'd' in d2.

d1 = {'a': [2, 4, 5, 6, 8, 10], 'b': [1, 2, 5, 6, 9, 12], 'c': [0, 4, 5, 8, 10, 21], 'e':[0,0,0]}
d2 = {'a': [12, 15], 'b': [14, 16], 'c': [23, 35], 'd': [13, 3]}

d2_keys_not_in_d1 = d2.keys() - d1.keys()
d1_keys_not_in_d2 = d1.keys() - d2.keys()
common_keys = d2.keys() & d1.keys()

for i in common_keys:
    d[i]=d1[i]+d2[i]
for i in d1_keys_not_in_d2:
    d[i]=d1[i]
for i in d2_keys_not_in_d1:
    d[i]=d2[i]
d
{'a': [2, 4, 5, 6, 8, 10, 12, 15],
 'b': [1, 2, 5, 6, 9, 12, 14, 16],
 'c': [0, 4, 5, 8, 10, 21, 23, 35],
 'd': [13, 3],
 'e': [0, 0, 0]}
cph_sto
  • 7,189
  • 12
  • 42
  • 78