将字典附加到字典?

Jav*_* C. 300 python dictionary

我有两个现有的词典,我希望将其中一个词典"追加"到另一个词典中.我的意思是,其他字典的关键值应该被制作成第一个字典.例如:

orig = {
   'A': 1,
   'B': 2,
   'C': 3,
}

extra = {
   'D': 4,
   'E': 5,
}

dest = # something here involving orig and extra

print dest
{
   'A': 1,
   'B': 2,
   'C': 3,
   'D': 4,
   'E': 5
}
Run Code Online (Sandbox Code Playgroud)

我认为这一切都可以通过for循环实现(也许?),但是有一些字典方法或任何其他模块可以为我保存这份工作吗?我正在使用的实际词典真的很大......

mip*_*adi 455

你可以做

orig.update(extra)
Run Code Online (Sandbox Code Playgroud)

或者,如果您不想orig修改,请先复制一份:

dest = dict(orig)  # or orig.copy()
dest.update(extra)
Run Code Online (Sandbox Code Playgroud)

请注意,如果extra和orig具有重叠键,则最终值将从extra中获取.例如,

>>> d1 = {1: 1, 2: 2}
>>> d2 = {2: 'ha!', 3: 3}
>>> d1.update(d2)
>>> d1
{1: 1, 2: 'ha!', 3: 3}
Run Code Online (Sandbox Code Playgroud)

  • 如果您的密钥不是有效的关键字参数,则会中断.例如`x = {1:1}; 字典(**X)` (12认同)
  • 使用`dict(**orig)`将创建一个新的临时字典,用作dict构造函数的关键字参数.然后构造函数将该参数中的值复制到自身中.所以你用`dict(**orig)`创建了一个额外的字典.当字典很大时,这就像在最初的问题中那样浪费. (4认同)
  • 有dict.copy(),它可以像你的复制方法那样生成浅拷贝. (3认同)

Nun*_*dré 68

最pythonic(和稍快)的方法是通过:

dest = {**orig, **extra}
Run Code Online (Sandbox Code Playgroud)

或者,根据要解决的问题,可能:

dest = {**orig, 'D': 4, 'E': 5}
Run Code Online (Sandbox Code Playgroud)

  • 遗憾的是它不适用于2.x((仅适用于3.x. (5认同)
  • 它不适用于我的家庭或工作笔记本电脑(3.4.3'final'0),但它在PythonAnywhere控制台(3.5.2)中有效.猜猜我应该升级什么的. (3认同)
  • dict(itertools.chain(d.items(),y.items())) (2认同)
  • 这是代码.我有Python 3.4.语法错误.`bob = {"a":"b"} bill = {"b":"c"} dest = {**bob,**bill}` (2认同)

And*_*ark 24

假设您不想更改orig,您可以像其他答案一样进行复制和更新,也可以通过将所有项目从两个词典传递到dict构造函数来一步创建新词典:

from itertools import chain
dest = dict(chain(orig.items(), extra.items()))
Run Code Online (Sandbox Code Playgroud)

或者没有itertools:

dest = dict(list(orig.items()) + list(extra.items()))
Run Code Online (Sandbox Code Playgroud)

请注意,您只需要通过结果items()list()关于Python 3,上2.X dict.items()已返回一个列表,以便你可以做dict(orig.items() + extra.items()).

作为一个更通用的用例,假设你有一个更大的dicts列表,你想要组合成一个单独的dict,你可以做这样的事情:

from itertools import chain
dest = dict(chain.from_iterable(map(dict.items, list_of_dicts)))
Run Code Online (Sandbox Code Playgroud)

  • 实际上我更喜欢这个,因为你可以在同一个表达式中"更新"你想要用作参数的字典,比如:`SomeClass(**dict(args.items()+ {'special':a_value,}. ()))` (2认同)

Joh*_*web 17

dict.update() 看起来它会做你想要的......

>> orig.update(extra)
>>> orig
{'A': 1, 'C': 3, 'B': 2, 'E': 5, 'D': 4}
>>> 
Run Code Online (Sandbox Code Playgroud)

但是,您可能不希望更新原始字典,但需要处理副本:

>>> dest = orig.copy()
>>> dest.update(extra)
>>> orig
{'A': 1, 'C': 3, 'B': 2}
>>> dest
{'A': 1, 'C': 3, 'B': 2, 'E': 5, 'D': 4}
Run Code Online (Sandbox Code Playgroud)


sle*_*erd 7

有.update()方法:)

更新([other]) 使用其他键中的键/值对更新字典,覆盖现有键.返回无.

update()接受另一个字典对象或一对键/值对的迭代(作为元组或长度为2的其他迭代).如果指定了关键字参数,则使用这些键/值对更新字典:d.update(red = 1,blue = 2).

版本2.4中更改:允许参数为键/值对的可迭代,并允许关键字参数.


kit*_*.eb 7

我想给出的答案是"使用collections.ChainMap",但我发现它只是在Python 3.3中添加:https : //docs.python.org/3.3/library/collections.html#chainmap-objects

您可以尝试从3.3源代码中删除类:http://hg.python.org/cpython/file/3.3/Lib/collections/ init .py#l763

这是一个功能较少的Python 2.x兼容版本(同一作者):http://code.activestate.com/recipes/305268-chained-map-lookups/

不是使用dict.merge扩展/覆盖另一个字典,也不是创建合并两者的附加副本,而是创建一个按顺序搜索的查找链.因为它不会复制它所包含的映射,所以ChainMap使用的内存非常少,并且可以看到以后对任何子映射的修改.因为顺序很重要,您还可以使用链来分层默认值(即用户首选项> config> env).


jkd*_*dev 5

组合或合并两个字典的三层式:

dest = {}
dest.update(orig)
dest.update(extra)
Run Code Online (Sandbox Code Playgroud)

这将创建一个新字典,dest而无需修改origextra

注意:如果键在orig和中具有不同的值extra,则将extra覆盖orig

  • 适用于 Python 2 和 Python 3。 (3认同)