有没有办法使用另一个dict在Python dict上设置多个默认值?

Dan*_*Lew 8 python dictionary

假设我在Python中有两个dicts:

mydict = { 'a': 0 }

defaults = {
    'a': 5,
    'b': 10,
    'c': 15
}
Run Code Online (Sandbox Code Playgroud)

我希望能够mydict使用默认值进行扩展defaults,这样'a'保持不变,但'b'和'c'被填充.我知道dict.setdefault()并且dict.update(),但每个只做我想要的一半 - 用dict.setdefault(),我必须遍历每个变量defaults; 但随着dict.update(),defaults将吹走任何预先存在的价值观mydict.

是否有一些我没有在Python中内置的功能可以做到这一点?如果没有,是否有更多Pythonic方式编写循环来重复调用,而dict.setdefaults()不是:

for key in defaults.keys():
    mydict.setdefault(key, defaults[key])
Run Code Online (Sandbox Code Playgroud)

上下文:我在Python中编写了一些控制如何解析XML树的数据.每个节点都有一个dict(即,如何处理每个节点),我宁愿我写的数据是稀疏的,但是用默认值填充.示例代码只是一个示例...实际代码在默认dict中有更多的键/值对.

(我意识到整个问题只是一个小小的狡辩,但它一直困扰着我,所以我想知道是否有更好的方法来做到这一点,我不知道.)

Sha*_*son 9

难道你不能让mydict成为默认副本,这样,mydict会有所有正确的值开始吗?

mydict = default.copy()
Run Code Online (Sandbox Code Playgroud)

  • @Daniel Lew:不会复制这些值,只是引用它们.新的dict将在内存中引用相同的值. (2认同)

ram*_*nes 8

从Python 3.9开始,你可以这样做:

mydict = defaults | mydict
Run Code Online (Sandbox Code Playgroud)

我发现这个解决方案在我的用例中是最优雅的。


Dzi*_*inX 5

如果您不介意在此过程中创建一个新字典,这可以解决问题:

newdict = dict(defaults)
newdict.update(mydict)
Run Code Online (Sandbox Code Playgroud)

现在newdict包含您需要的内容。


Dar*_*con 5

您可以像Python的collections.DefaultDict一样工作:

class MultiDefaultDict(dict):
    def __init__(self, defaults, **kwargs):
        self.defaults = defaults
        self.update(kwargs)
    def __missing__(self, key):
        return self.defaults[key]

>>> mydict2 = MultiDefaultDict(defaults, a=0)
>>> mydict2['a']
0
>>> mydict2['b']
10
>>> mydict2
{'a': 0}
Run Code Online (Sandbox Code Playgroud)

到目前为止发布的其他解决方案复制了所有默认值; 这个人按要求分享他们.您可能希望也可能不希望覆盖其他dict方法,如__contains __(),__ item __(),items(),keys(),values() - 此处定义的此类仅迭代非默认项.