11

我正在寻找最有效和 Pythonic(主要是有效)的方式来更新字典,但如果存在现有键,则保留旧值。例如...

myDict1 = {'1': ('3', '2'), '3': ('2', '1'), '2': ('3', '1')}
myDict2 = {'4': ('5', '2'), '5': ('2', '4'), '2': ('5', '4')}

myDict1.update(myDict2) gives me the following....

{'1': ('3', '2'), '3': ('2', '1'), '2': ('5', '4'), '5': ('2', '4'), '4': ('5', '2')}

请注意键“2”如何存在于两个字典中并且曾经具有值(“3”,“1”),但现在它具有来自 myDict2 中的键的值(“5”,“4”)?

有没有办法以有效的方式更新字典,以便键'2'最终具有值('3','1','5','4')?#不分先后顺序

提前致谢

4

5 回答 5

10

我认为最有效的方法是这样的:

for k, v in myDict2.iteritems():
    myDict1[k] = myDict1.get(k, ()) + v

update不幸的是,没有与您想要做的等效的东西。

于 2013-05-25T01:32:08.660 回答
5

2 个就地更新操作有什么问题?

myDict2.update(myDict1)
myDict1.update(myDict2)

说明:第一次更新将用 myDict1 中的值覆盖已经存在的键,并在 myDict2 中插入所有不存在的键值对。

第二次更新将用来自 myDict2 的值覆盖 myDict1 中已经存在的键,由于第一次操作,这些值实际上是来自 myDict1 本身的值。插入的任何新键值对都将来自原始 myDict2。

这当然取决于您不关心保留 myDict2 的事实

更新:使用 python3,您无需触摸 myDict2 即可执行此操作

myDict1 = {**myDict1, **myDict2, **myDict1}

这实际上与

myDict1 = {**myDict2, **myDict1}

输出

{'1': ('3', '2'), '3': ('2', '1'), '2': ('3', '1'), '4': ('5', '2'), '5': ('2', '4')}
于 2019-12-05T10:01:45.067 回答
4

合并大型字典的最快方法是引入一个中间对象,该对象的行为就好像字典被合并而不实际合并它们(请参阅@Raymond Hettinger 的答案):

from collections import ChainMap

class MergedMap(ChainMap):
    def __getitem__(self, key):
        result = []
        found = False
        for mapping in self.maps:
            try:
                result.extend(mapping[key])
                found = True
            except KeyError:
                pass
        return result if found else self.__missing__(key)

merged = MergedMap(myDict1, myDict2)

它是否适用取决于您以后要如何使用组合的dict。

collections.ChainMap为了方便提供完整的MutableMapping界面,它使用Python 3.3+;您只能实现在旧 Python 版本上使用的部分。

于 2013-05-25T03:21:34.293 回答
3

也许defaultdict会有所帮助

from collections import defaultdict
myDict0= {'1': ('3', '2'), '3': ('2', '1'), '2': ('3', '1')}
myDict2 = {'4': ('5', '2'), '5': ('2', '4'), '2': ('5', '4')}
myDict1 = defaultdict(list)
for (key, value) in myDict0.iteritems():
     myDict1[key].extend(value)

for (key, value) in myDict2.iteritems():
     myDict1[key].extend(value)

print myDict1
defaultdict(<type 'list'>, {'1': ['3', '2'], '3': ['2', '1'], '2': ['3', '1', '5', '4'], '5': ['2', '4'], '4': ['5', '2']})
于 2013-05-25T01:44:55.700 回答
0

不,恐怕没有简单的方法可以做到这一点。

最好的方法可能是迭代和合并。就像是:

for key in myDict1.iterkeys():
    # Thank you to user2246674 and Nolen Royalty to help me optimise this in their comments 
    if key in myDict2:
        myDict2[key] = myDict2[key] + myDict1[key]
    else:
        myDict2[key] = myDict1[key]
于 2013-05-25T01:25:54.950 回答