Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Updating a python dictionary while adding to existing keys?

I'm looking for the most efficient and pythonic (mainly efficient) way to update a dictionary but keep the old values if an existing key is present. For example...

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')}

notice how the key '2' exists in both dictionaries and used to have values ('3', '1') but now it has the values from it's key in myDict2 ('5', '4')?

Is there a way to update the dictionary in an efficient manner so as the key '2' ends up having values ('3', '1', '5', '4')? #in no particular order

Thanks in advance

like image 597
Ogen Avatar asked May 25 '13 01:05

Ogen


People also ask

What happens if you assign a new value to a dictionary using a key that already exists?

If the key is already present in the dictionary, it gets overwritten with the new value.

Can we update the key in dictionary Python?

Python Dictionary update() Method It inserts key/value if it is not present. It updates key/value if it is already present in the dictionary. It also allows an iterable of key/value pairs to update the dictionary. like: update(a=10,b=20) etc.

How do I add elements to an existing dictionary?

To append an element to an existing dictionary, you have to use the dictionary name followed by square brackets with the key name and assign a value to it.


3 Answers

I think the most effective way to do it would be something like this:

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

But there isn't an update equivalent for what you're looking to do, unfortunately.

like image 160
Nolen Royalty Avatar answered Nov 15 '22 19:11

Nolen Royalty


What is wrong with 2 in-place update operations?

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

Explanation: The first update will overwrite the already existing keys with the values from myDict1, and insert all key value pairs in myDict2 which don't exist.

The second update will overwrite the already existing keys in myDict1 with values from myDict2, which are actually the values from myDict1 itself due to the 1st operation. Any new key value pairs inserted will be from the original myDict2.

This of course is conditional to the fact that you don't care about preserving myDict2

Update: With python3, you can do this without having to touch myDict2

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

which would actually be same as

myDict1 = {**myDict2, **myDict1}

Output

{'1': ('3', '2'), '3': ('2', '1'), '2': ('3', '1'), '4': ('5', '2'), '5': ('2', '4')}
like image 22
Ehtesham Siddiqui Avatar answered Nov 15 '22 20:11

Ehtesham Siddiqui


The fastest way to merge large dictionaries is to introduce an intermediate object that behaves as though the dicts are merged without actually merging them (see @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)

Whether it is applicable depends on how you want to use the combined dict later.

It uses collections.ChainMap from Python 3.3+ for convenience to provide the full MutableMapping interface; you could implement only parts that you use on older Python versions.

like image 45
jfs Avatar answered Nov 15 '22 21:11

jfs