dictionary:如何连接两个词典在Python中创建一个新词典?

本问题已经有最佳答案,请猛点这里访问。

假设我有三个骰子

1
2
3
d1={1:2,3:4}
d2={5:6,7:9}
d3={10:8,13:22}

我如何创建一个新的d4组合这三个字典?例如:

1
d4={1:2,3:4,5:6,7:9,10:8,13:22}


在Python3中最慢且不起作用:连接items并在结果列表上调用dict:

1
2
3
4
$ python -mtimeit -s'd1={1:2,3:4}; d2={5:6,7:9}; d3={10:8,13:22}' \
'd4 = dict(d1.items() + d2.items() + d3.items())'

100000 loops, best of 3: 4.93 usec per loop

最快:充分利用dict构造函数,然后一个update:

1
2
3
4
$ python -mtimeit -s'd1={1:2,3:4}; d2={5:6,7:9}; d3={10:8,13:22}' \
'd4 = dict(d1, **d2); d4.update(d3)'

1000000 loops, best of 3: 1.88 usec per loop

中间:一个update循环调用一个初始为空的dict:

1
2
3
4
$ python -mtimeit -s'd1={1:2,3:4}; d2={5:6,7:9}; d3={10:8,13:22}' \
'd4 = {}' 'for d in (d1, d2, d3): d4.update(d)'

100000 loops, best of 3: 2.67 usec per loop

或者,等价地,一个复制器和两个更新:

1
2
3
4
$ python -mtimeit -s'd1={1:2,3:4}; d2={5:6,7:9}; d3={10:8,13:22}' \
'd4 = dict(d1)' 'for d in (d2, d3): d4.update(d)'

100000 loops, best of 3: 2.65 usec per loop

我建议使用方法(2),并特别建议避免使用方法(1)(它还占用O(N)额外的辅助内存,用于连接项目列表的临时数据结构)。


1
d4 = dict(d1.items() + d2.items() + d3.items())

或者(而且应该更快):

1
2
3
d4 = dict(d1)
d4.update(d2)
d4.update(d3)

之前的问题这两个答案都来自这里。


您可以使用update()方法构建一个包含所有条目的新字典:

1
2
3
4
dall = {}
dall.update(d1)
dall.update(d2)
dall.update(d3)

或者,在一个循环中:

1
2
3
dall = {}
for d in [d1, d2, d3]:
  dall.update(d)


使用dict构造函数

1
2
3
4
5
d1={1:2,3:4}
d2={5:6,7:9}
d3={10:8,13:22}

d4 = reduce(lambda x,y: dict(x, **y), (d1, d2, d3))

作为一个函数

1
2
from functools import partial
dict_merge = partial(reduce, lambda a,b: dict(a, **b))

使用dict.update()方法可以消除创建中间字典的开销:

1
2
3
from functools import reduce
def update(d, other): d.update(other); return d
d4 = reduce(update, (d1, d2, d3), {})

这里有一个单行程序(imports don't count:),可以很容易地推广到连接N个字典:

Python 2.6 +

1
2
from itertools import chain
dict(chain.from_iterable(d.iteritems() for d in (d1, d2, d3))

输出:

1
2
3
4
5
6
>>> from itertools import chain
>>> d1={1:2,3:4}
>>> d2={5:6,7:9}
>>> d3={10:8,13:22}
>>> dict(chain.from_iterable(d.iteritems() for d in (d1, d2, d3)))
{1: 2, 3: 4, 5: 6, 7: 9, 10: 8, 13: 22}

广义到串联N个词:

1
2
3
from itertools import chain
def dict_union(*args):
    return dict(chain.from_iterable(d.iteritems() for d in args))

Python 3

1
2
from itertools import chain
dict(chain.from_iterable(d.items() for d in (d1, d2, d3)))

和:

1
2
3
from itertools import chain
def dict_union(*args):
    return dict(chain.from_iterable(d.items() for d in args))

我来晚了一点,我知道,但我希望这能对别人有所帮助。