如何在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()
你可以使用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)
合并字典的视图意味着什么,因为视图总是反映相应字典的内容。
因此,要想有不同的视图,要么编辑其中一个词典,要么实例化一个新词典(就像你所做的那样),就没有办法解决它。见this。
但也许你想要的是itertools.chain
迭代多个迭代。这种解决方案并不能让人满意。或者正如其他人所说的collections.ChainMap
。我会使用chain
迭代和ChainMap
进行查找。
你可以使用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()
你可以使用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())