添加到现有密钥时更新python字典?

时间:2013-05-25 01:19:58

标签: python performance dictionary

我正在寻找最有效和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')中有来自它的键的值?< / p>

有没有办法以有效的方式更新字典,因为键'2'最终有值('3','1','5','4')? #in no specific order

提前致谢

5 个答案:

答案 0 :(得分:9)

我认为最有效的方法是:

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

但遗憾的是,没有update相当于你想要做的事情。

答案 1 :(得分: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']})

答案 2 :(得分:3)

合并大字典的最快方法是引入一个中间对象,其行为就像合并了dicts而不实际合并它们一样(参见@Raymond Hettinger's answer):

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)

是否适用取决于您以后如何使用合并后的字典。

它使用Python 3.3+中的collections.ChainMap以方便提供完整的MutableMapping接口;您只能实现在较旧的Python版本上使用的部分。

答案 3 :(得分:2)

两次就地更新操作有什么问题?

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

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

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

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

答案 4 :(得分: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]