# 如何在单个表达式中合并两个字典？

``````>>> x = {'a':1, 'b': 2}
>>> y = {'b':10, 'c': 11}
>>> z = x.update(y)
>>> print(z)
None
>>> x
{'a': 1, 'b': 10, 'c': 11}``````

（为了更加清楚，最后一次冲突处理`dict.update()`也是我所追求的。）

# 我如何在一个表达式中合并两个Python字典？

• 在Python 3.5或更高版本中，：
``z = {**x, **y}``
• 在Python 2中（或3.4或更低版本）编写一个函数：
``````def merge_two_dicts(x, y):
z = x.copy()   # start with x's keys and values
z.update(y)    # modifies z with y's keys and values & returns None
return z``````

``z = merge_two_dicts(x, y)``

## 说明

``````x = {'a': 1, 'b': 2}
y = {'b': 3, 'c': 4}``````

``````>>> z
{'a': 1, 'b': 3, 'c': 4}``````

``z = {**x, **y}``

``````z = x.copy()
z.update(y) # which returns None since it mutates z``````

# 还没有在Python 3.5上，但想要一个表达式

``````def merge_two_dicts(x, y):
"""Given two dicts, merge them into a new dict as a shallow copy."""
z = x.copy()
z.update(y)
return z``````

``z = merge_two_dicts(x, y)``

``````def merge_dicts(*dict_args):
"""
Given any number of dicts, shallow copy and merge into a new dict,
precedence goes to key value pairs in latter dicts.
"""
result = {}
for dictionary in dict_args:
result.update(dictionary)
return result``````

``z = merge_dicts(a, b, c, d, e, f, g) ``

# 对其他答案的批评

``z = dict(x.items() + y.items())``

``````>>> c = dict(a.items() + b.items())
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for +: 'dict_items' and 'dict_items'``````

``>>> c = dict(a.items() | b.items())``

``````>>> x = {'a': []}
>>> y = {'b': []}
>>> dict(x.items() | y.items())
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'``````

``````>>> x = {'a': 2}
>>> y = {'a': 1}
>>> dict(x.items() | y.items())
{'a': 2}``````

``z = dict(x, **y)``

``````>>> c = dict(a, **b)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: keyword arguments must be strings``````

``dict(a=1, b=10, c=11)``

``{'a': 1, 'b': 10, 'c': 11}``

## 回应评论

``````>>> foo(**{('a', 'b'): None})
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: foo() keywords must be strings
>>> dict(**{('a', 'b'): None})
{('a', 'b'): None}``````

`dict(x.items() + y.items())` 仍然是Python 2最可读的解决方案。可读性计数。

# 性能较差但正确的临时组

``{k: v for d in dicts for k, v in d.items()} # iteritems in Python 2.7``

``dict((k, v) for d in dicts for k, v in d.items())``

`itertools.chain` 会按照正确的顺序将迭代器链接到键值对上：

``````import itertools
z = dict(itertools.chain(x.iteritems(), y.iteritems()))``````

# 性能分析

``import timeit``

``````>>> min(timeit.repeat(lambda: merge_two_dicts(x, y)))
0.5726828575134277
>>> min(timeit.repeat(lambda: {k: v for d in (x, y) for k, v in d.items()} ))
1.163769006729126
>>> min(timeit.repeat(lambda: dict(itertools.chain(x.iteritems(), y.iteritems()))))
1.1614501476287842
>>> min(timeit.repeat(lambda: dict((k, v) for d in (x, y) for k, v in d.items())))
2.2345519065856934``````

``````>>> min(timeit.repeat(lambda: {**x, **y}))
0.4094954460160807
>>> min(timeit.repeat(lambda: merge_two_dicts(x, y)))
0.7881555100320838
>>> min(timeit.repeat(lambda: {k: v for d in (x, y) for k, v in d.items()} ))
1.4525277839857154
>>> min(timeit.repeat(lambda: dict(itertools.chain(x.items(), y.items()))))
2.3143140770262107
>>> min(timeit.repeat(lambda: dict((k, v) for d in (x, y) for k, v in d.items())))
3.2069112799945287``````