Python“扩展”为字典

Python “extend” for a dictionary

用另一本词典扩充词典的最佳方法是什么?例如:

1
2
3
4
5
6
>>> a = {"a" : 1,"b" : 2 }
>>> b = {"c" : 3,"d" : 4 }
>>> a
{'a': 1, 'b': 2}
>>> b
{'c': 3, 'd': 4}

我正在寻找任何操作来获得这个避免for循环:

1
{"a" : 1,"b" : 2,"c" : 3,"d" : 4 }

我想做如下的事情:

1
a.extend(b)  # This does not work


1
a.update(b)

最新的python标准库文档


在这个封闭的问题中,一块美丽的宝石:

"一行法",改变两个输入指令,是

1
basket = dict(basket_one, **basket_two)

了解**basket_two(**)在这里的含义。

如果发生冲突,basket_two中的项目将覆盖basket_one中的项目。正如一句话所说,这是非常易读和透明的,我对任何时候使用它都没有任何后悔,因为一个混合了两个词的口述很有用(任何读者如果不能理解它,事实上会很好地服务于这样的方式,提示他或她学习关于dict**形式;-)。例如,使用如下:

1
x = mungesomedict(dict(adict, **anotherdict))

在我的代码中是相当频繁的事件。

最初由Alex Martelli提交

注意:在python 3中,只有当basket_2中的每个键都是一个string时,这才有效。


您是否尝试使用字典理解和字典映射:

1
2
c = {**a, **b}
# c = {"a" : 1,"b" : 2,"c" : 3,"d" : 4 }


1
a.update(b)

将添加从B到A的键和值,如果已经有键的值,则覆盖。


正如其他人所提到的,对于某些口述,a.update(b)ab将达到您在问题中要求的结果。然而,我想指出的是,我多次看到extend映射/设置对象的方法希望在语法a.extend(b)中,a的值不应该被b的值覆盖。a.update(b)覆盖了a的值,因此对extend来说不是一个好的选择。

注意,有些语言称这种方法为defaultsinject,因为它可以被认为是一种将b的值(可能是一组默认值)注入字典的方法,而不重写可能已经存在的值。

当然,您可以简单地注意到,a.extend(b)b.update(a); a=b几乎相同。要删除分配,可以这样做:

1
2
3
4
5
6
7
8
def extend(a,b):
   """Create a new dictionary with a's properties extended by b,
    without overwriting.

    >>> extend({'a':1,'b':2},{'b':3,'c':4})
    {'a': 1, 'c': 4, 'b': 2}
   """

    return dict(b,**a)

多亏了Tom Leys的聪明想法,他为extend使用了一个无副作用的dict构造函数。


您还可以使用python的collections.chainmap,这是在python 3.3中引入的。

1
2
3
from collections import Chainmap
c = Chainmap(a, b)
c['a'] # returns 1

这有一些可能的优点,这取决于您的用例。这里将对它们进行更详细的解释,但我将简要概述:

  • 链图只使用字典的视图,因此实际上不复制任何数据。这会导致更快的链接(但查找速度较慢)
  • 实际上不会覆盖任何键,因此,如果需要,您可以知道数据是来自A还是B。

这主要使它对配置字典之类的东西有用。