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

tim*_*imy 210 python dictionary concatenation

说我有三个词

d1={1:2,3:4}
d2={5:6,7:9}
d3={10:8,13:22}
Run Code Online (Sandbox Code Playgroud)

如何创建一个d4结合这三个词典的新内容?即:

d4={1:2,3:4,5:6,7:9,10:8,13:22}
Run Code Online (Sandbox Code Playgroud)

Ale*_*lli 247

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

    $ 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
    
    Run Code Online (Sandbox Code Playgroud)
  2. 最快:利用dict构造函数到刀柄,然后一个update:

    $ 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
    
    Run Code Online (Sandbox Code Playgroud)
  3. Middling:update对最初空的dict的一个循环调用:

    $ 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
    
    Run Code Online (Sandbox Code Playgroud)
  4. 或者,等效地,一个copy-ctor和两个更新:

    $ 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
    
    Run Code Online (Sandbox Code Playgroud)

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

  • 除非已知所有键都是字符串,否则选项2是滥用Python 2实现细节(事实上,在C中实现的某些内置函数绕过了对关键字参数的预期检查).在Python 3(和PyPy)中,选项2将使用非字符串键失败. (37认同)
  • 上面的1是最好的,如果在小的dicts工作,因为我认为更清楚. (13认同)
  • 我想补充一点,`d1.items()+ d2.items()`在Python 3中不起作用. (11认同)
  • 我不明白为什么`d4 = dict(d1,**dict(d2,**d3))`并不比#2快,但事实并非如此. (7认同)
  • 在Python 3.5+中,可以使用`**'表示法:`d1 = {1:2,3:4}; D2 = {5:6,7:9}; D3 = {10:8,13:22}; d4 = {**d1,**d2,**d3}`,这对我来说比上面的#3或#4快近3倍(每个循环0.228 usec与#3或4分别为0.661或0.595 usec) .如上所述,#1和#2不适用于Python 3. (5认同)
  • 只是偶然发现了这个线程,我使用`d4 = d1.copy()一直得到~0.2 usec更快的结果 d4.update(d2,**d3)`比`d4 = dict(d1,**d2); d4.update(D3)`.我知道这已经老了,但我想我会发布我的结果. (3认同)
  • 这是非常难以理解的 (3认同)
  • 如果你忽略导入 `itertools` 的时间损失,那么 `dict(itertools.chain(d1.items(), d2.items(), d3.items()))` 似乎也是一个竞争者。 (2认同)
  • dict理解怎么样?```D1 = {1:2,3:4}; D2 = {5:6,7:9}; D3 = {10:8,13:22}; D4 = {10:11,12:13}; d5 = {k:v代表d [d1,d2,d3,d4]代表k,v代表d.items()}```不知怎的,我得到:```10000000循环,最好的3:0.0371 usec每循环```与上面显示的计算时间几乎相同(Python 2.7.12和Python 3.5.2) (2认同)

Amb*_*ber 112

d4 = dict(d1.items() + d2.items() + d3.items())
Run Code Online (Sandbox Code Playgroud)

或者(并且应该更快):

d4 = dict(d1)
d4.update(d2)
d4.update(d3)
Run Code Online (Sandbox Code Playgroud)

之前的问题是这两个答案都来自于此.

  • 第一个版本不适用于Python3. (15认同)
  • 它确实可以在 Python 3 中工作,但是您必须将“dict_items”对象转换为真正的“list”对象。这是 Python 3 优先考虑较小的性能优化而不是简单性和易用性的另一个例子。 (2认同)

sth*_*sth 57

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

dall = {}
dall.update(d1)
dall.update(d2)
dall.update(d3)
Run Code Online (Sandbox Code Playgroud)

或者,在循环中:

dall = {}
for d in [d1, d2, d3]:
  dall.update(d)
Run Code Online (Sandbox Code Playgroud)

  • @AJRouvoet:在这种情况下,"原始的"是`dall`中一个全新的空字典.这个新词典反复更新以包含所有元素.故意"dall"被改变了. (4认同)
  • update 不会构建新字典。它(如预期)更新了原始的。 (3认同)
  • 啊,我的评论纯粹是针对你第一句话的措辞方式。它暗示了一些事实并非如此。尽管我承认投反对票可能有点严厉。 (2认同)

小智 26

使用dict构造函数

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))
Run Code Online (Sandbox Code Playgroud)

作为一个功能

from functools import partial
dict_merge = partial(reduce, lambda a,b: dict(a, **b))
Run Code Online (Sandbox Code Playgroud)

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

from functools import reduce
def update(d, other): d.update(other); return d
d4 = reduce(update, (d1, d2, d3), {})
Run Code Online (Sandbox Code Playgroud)


ron*_*man 23

这是一个单行(imports不计数:),可以很容易地推广到连接N个字典:

Python 2.6+

from itertools import chain
dict(chain.from_iterable(d.iteritems() for d in (d1, d2, d3))
Run Code Online (Sandbox Code Playgroud)

输出:

>>> 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}
Run Code Online (Sandbox Code Playgroud)

广义连接N dicts:

from itertools import chain
def dict_union(*args):
    return dict(chain.from_iterable(d.iteritems() for d in args))
Run Code Online (Sandbox Code Playgroud)

Python 3

from itertools import chain
dict(chain.from_iterable(d.items() for d in (d1, d2, d3)))
Run Code Online (Sandbox Code Playgroud)

和:

from itertools import chain
def dict_union(*args):
    return dict(chain.from_iterable(d.items() for d in args))
Run Code Online (Sandbox Code Playgroud)

我知道,我参加这个派对有点晚了,但我希望这对某人有所帮助.

  • “进口” *做*计数。但是这里的解决方案仍然很有趣 (3认同)