Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Updating nested dictionaries when data has existing key

I am trying to update values in a nested dictionary, without over-writting previous entries when the key already exists. For example, I have a dictionary:

  myDict = {}
  myDict["myKey"] = { "nestedDictKey1" : aValue }

giving,

 print myDict
>> { "myKey" : { "nestedDictKey1" : aValue }}

Now, I want to add another entry , under "myKey"

myDict["myKey"] = { "nestedDictKey2" : anotherValue }}

This will return:

print myDict
>> { "myKey" : { "nestedDictKey2" : anotherValue }}

But I want:

print myDict
>> { "myKey" : { "nestedDictKey1" : aValue , 
                 "nestedDictKey2" : anotherValue }}

Is there a way to update or append "myKey" with new values, without overwriting the previous ones?

like image 443
eric Avatar asked Nov 25 '14 04:11

eric


People also ask

How do you change a value in a nested dictionary?

Adding or updating nested dictionary items is easy. Just refer to the item by its key and assign a value. If the key is already present in the dictionary, its value is replaced by the new one. If the key is new, it is added to the dictionary with its value.

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. The keys can also be passed as keyword arguments to this method with their corresponding values, like dictionary. update(new_key=new_value) .

Can we update the value of a key in dictionary?

Note: The update() method adds element(s) to the dictionary if the key is not in the dictionary. If the key is in the dictionary, it updates the key with the new value.

How do we add data to a dictionary that is already started?

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.


5 Answers

This is a very nice general solution to dealing with nested dicts:

import collections
def makehash():
    return collections.defaultdict(makehash)

That allows nested keys to be set at any level:

myDict = makehash()
myDict["myKey"]["nestedDictKey1"] = aValue
myDict["myKey"]["nestedDictKey2"] = anotherValue
myDict["myKey"]["nestedDictKey3"]["furtherNestedDictKey"] = aThirdValue

For a single level of nesting, defaultdict can be used directly:

from collections import defaultdict
myDict = defaultdict(dict)
myDict["myKey"]["nestedDictKey1"] = aValue
myDict["myKey"]["nestedDictKey2"] = anotherValue

And here's a way using only dict:

try:
  myDict["myKey"]["nestedDictKey2"] = anotherValue
except KeyError:
  myDict["myKey"] = {"nestedDictKey2": anotherValue}
like image 141
Allen Luce Avatar answered Nov 16 '22 00:11

Allen Luce


You can use collections.defaultdict for this, and just set the key-value pairs within the nested dictionary.

from collections import defaultdict
my_dict = defaultdict(dict)
my_dict['myKey']['nestedDictKey1'] = a_value
my_dict['myKey']['nestedDictKey2'] = another_value

Alternatively, you can also write those last 2 lines as

my_dict['myKey'].update({"nestedDictKey1" : a_value })
my_dict['myKey'].update({"nestedDictKey2" : another_value })
like image 29
Stuart Avatar answered Nov 15 '22 23:11

Stuart


You can write a generator to update key in nested dictionary, like this.

def update_key(key, value, dictionary):
        for k, v in dictionary.items():
            if k == key:
                dictionary[key]=value
            elif isinstance(v, dict):
                for result in update_key(key, value, v):
                    yield result
            elif isinstance(v, list):
                for d in v:
                    if isinstance(d, dict):
                        for result in update_key(key, value, d):
                            yield result

list(update_key('Any level key', 'Any value', DICTIONARY))
like image 30
Manoj Datt Avatar answered Nov 16 '22 01:11

Manoj Datt


from ndicts.ndicts import NestedDict

nd = NestedDict()
nd["myKey", "nestedDictKey1"] = 0
nd["myKey", "nestedDictKey2"] = 1
>>> nd
NestedDict({'myKey': {'nestedDictKey1': 0, 'nestedDictKey2': 1}})
>>> nd.to_dict()
{'myKey': {'nestedDictKey1': 0, 'nestedDictKey2': 1}}

To install ndicts pip install ndicts

like image 41
edd313 Avatar answered Nov 15 '22 23:11

edd313


You could treat the nested dict as immutable:

myDict["myKey"] = dict(myDict["myKey"], **{ "nestedDictKey2" : anotherValue })

like image 42
Albert James Teddy Avatar answered Nov 15 '22 23:11

Albert James Teddy