在python中合并两个字典视图

问题描述 投票:2回答:4

如何在python中合并两个dicts的项目的视图?

我的用例是:我在课堂上有两个私人词典。我希望API将它们视为一个,并提供items方法。我知道的唯一方法是将它们组合起来,然后提供两者的视图,但对于大型词典,这似乎很昂贵。我想的是像a.items() + b.items()

注意:我不关心钥匙冲突。

这就是我想改进的地方:

class A:
    _priv1 = {'a': 1, 'b': 2}
    _priv2 = {'c': 1, 'd': 2}

    def items(self):
        return {**self._priv1, **self._priv2}.items()
python dictionary merge
4个回答
1
投票

你可以使用ChainMap

from collections import ChainMap

class A:
    _priv1 = {'a': 1, 'b': 2}
    _priv2 = {'c': 1, 'd': 2}

    def items(self):
        return ChainMap(self._priv1, self._priv2)

1
投票

合并字典的视图意味着什么,因为视图总是反映相应字典的内容。

因此,要想有不同的视图,要么编辑其中一个词典,要么实例化一个新词典(就像你所做的那样),就没有办法解决它。见this

但也许你想要的是itertools.chain迭代多个迭代。这种解决方案并不能让人满意。或者正如其他人所说的collections.ChainMap。我会使用chain迭代和ChainMap进行查找。


1
投票

你可以使用ChainMap

ChainMap将多个dicts或其他映射组合在一起以创建单个可更新视图。如果未指定映射,则提供单个空字典,以便新链始终至少具有一个映射。

from collections import ChainMap
context = ChainMap(_priv1, _priv2, ...)

例:

In [3]: _priv1 = {1: 2, 3: 4}

In [4]: _priv2 = {5: 6, 7: 8}

In [5]: from collections import ChainMap
   ...: context = ChainMap(_priv1, _priv2)

In [6]: context
Out[6]: ChainMap({1: 2, 3: 4}, {5: 6, 7: 8})

In [7]: _priv1.update({9: 10})

In [8]: context
Out[8]: ChainMap({1: 2, 3: 4, 9: 10}, {5: 6, 7: 8})

In [9]: context.get(9)
Out[9]: 10

对于您的代码示例,我将使用:

from collections import ChainMap

class A:
    _priv1 = {'a': 1, 'b': 2}
    _priv2 = {'c': 1, 'd': 2}
    _union_dict = ChainMap(_priv1, _priv2)

    @classmethod
    def items(cls):
        return cls._union_dict.items()

0
投票

你可以使用chain两个结合两个或更多的视图。就像声明的那样:

创建一个迭代器,它返回第一个iterable中的元素,直到它耗尽,然后进入下一个iterable,直到所有的iterables都用完为止。

这样就不会复制数据了。

from itertools import chain

class A:
    _priv1 = {'a': 1, 'b': 2}
    _priv2 = {'c': 1, 'd': 2}

    def items(self):
        return chain(self._priv1.items(), self._priv2.items())
© www.soinside.com 2019 - 2024. All rights reserved.