我正在寻找最有效和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
提前致谢
答案 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]