26

I am trying to merge the following python dictionaries as follow:

dict1= {'paul':100, 'john':80, 'ted':34, 'herve':10}
dict2 = {'paul':'a', 'john':'b', 'ted':'c', 'peter':'d'}

output = {'paul':[100,'a'],
          'john':[80, 'b'],
          'ted':[34,'c'],
          'peter':[None, 'd'],
          'herve':[10, None]}

Is there an efficient way to do this?

yugr
  • 16,844
  • 3
  • 43
  • 82
Joey
  • 4,901
  • 7
  • 25
  • 27
  • I wish to keep all keys from both dictionaries – Joey Mar 02 '10 at 19:11
  • 8
    Please don't add comments to your own question. It's *your* question. You can update the question so that it's correct. Comments are for others to comment on your question. – S.Lott Mar 02 '10 at 19:13
  • 1
    A little formatting would go a long way here. Try editing your question: select the code and click the "101 010" button in the edit window. Also, separate dict1 & dict2 into two separate lines. – Pete Mar 02 '10 at 19:19
  • [@rcreswick's answer](http://stackoverflow.com/questions/38987/how-can-i-merge-two-python-dictionaries-as-a-single-expression/44512#44512) to this question should suit your needs. – Seth Mar 02 '10 at 19:15
  • **See also:** [similar question](https://stackoverflow.com/questions/9415785/merging-several-python-dictionaries) – dreftymac Dec 11 '17 at 21:07

4 Answers4

22
output = {k: [dict1[k], dict2.get(k)] for k in dict1}
output.update({k: [None, dict2[k]] for k in dict2 if k not in dict1})
yugr
  • 16,844
  • 3
  • 43
  • 82
Alex Martelli
  • 811,175
  • 162
  • 1,198
  • 1,373
  • Could you elaborate on why this works? What is the object being passed to `dict()` and `update()`? Is it a generator? – Heisenberg Feb 09 '15 at 21:57
  • 1
    @Heisenberg, they're **generator expressions** (AKA "genexp"s), the generator equivalent of "list comprehensions" (AKA "listcomp"s) -- a handy way to make a generator in-line (saves transient use of memory compared to the equivalent listcomp, if the list is not needed later -- as it wouldn't be here since `dict` and `update` both just need some kind of iterator yielding 2-item tuples taken as `(key, value)`). – Alex Martelli Feb 10 '15 at 00:48
16

This will work:

{k: [dict1.get(k), dict2.get(k)] for k in set(dict1.keys() + dict2.keys())}

Output:

{'john': [80, 'b'], 'paul': [100, 'a'], 'peter': [None, 'd'], 'ted': [34, 'c'], 'herve': [10, None]}
yugr
  • 16,844
  • 3
  • 43
  • 82
Nadia Alramli
  • 105,894
  • 35
  • 170
  • 151
9

In Python2.7 or Python3.1 you can easily generalise to work with any number of dictionaries using a combination of list, set and dict comprehensions!

>>> dict1 = {'paul':100, 'john':80, 'ted':34, 'herve':10}
>>> dict2 = {'paul':'a', 'john':'b', 'ted':'c', 'peter':'d'}
>>> dicts = dict1,dict2
>>> {k:[d.get(k) for d in dicts] for k in {k for d in dicts for k in d}}
{'john': [80, 'b'], 'paul': [100, 'a'], 'peter': [None, 'd'], 'ted': [34, 'c'], 'herve': [10, None]}

Python2.6 doesn't have set comprehensions or dict comprehensions

>>> dict1 = {'paul':100, 'john':80, 'ted':34, 'herve':10}
>>> dict2 = {'paul':'a', 'john':'b', 'ted':'c', 'peter':'d'}
>>> dicts = dict1,dict2
>>> dict((k,[d.get(k) for d in dicts]) for k in set(k for d in dicts for k in d))
{'john': [80, 'b'], 'paul': [100, 'a'], 'peter': [None, 'd'], 'ted': [34, 'c'], 'herve': [10, None]}
John La Rooy
  • 281,034
  • 50
  • 354
  • 495
2

In Python3.1,

output = {k:[dict1.get(k),dict2.get(k)] for k in dict1.keys() | dict2.keys()}
In Python2.6,
output = dict((k,[dict1.get(k),dict2.get(k)]) for k in set(dict1.keys() + dict2.keys()))
asdfg
  • 2,341
  • 2
  • 25
  • 24