Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Setting a value in a nested Python dictionary given a list of indices and value

I'm trying to programmatically set a value in a dictionary, potentially nested, given a list of indices and a value.

So for example, let's say my list of indices is:

['person', 'address', 'city'] 

and the value is

'New York' 

I want as a result a dictionary object like:

{ 'Person': { 'address': { 'city': 'New York' } } 

Basically, the list represents a 'path' into a nested dictionary.

I think I can construct the dictionary itself, but where I'm stumbling is how to set the value. Obviously if I was just writing code for this manually it would be:

dict['Person']['address']['city'] = 'New York' 

But how do I index into the dictionary and set the value like that programmatically if I just have a list of the indices and the value?

Python

like image 270
peterk Avatar asked Dec 03 '12 16:12

peterk


People also ask

How do you get a value in a nested dictionary Python?

Access Values using get() Another way to access value(s) in a nested dictionary ( employees ) is to use the dict. get() method. This method returns the value for a specified key. If the specified key does not exist, the get() method returns None (preventing a KeyError ).

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.

How do you make a nested dictionary dynamically in Python?

In Python, a Nested dictionary can be created by placing the comma-separated dictionaries enclosed within braces.

Can I implement nested dictionary with list?

Given a list and dictionary, map each element of list with each item of dictionary, forming nested dictionary as value. Explanation : Index-wise key-value pairing from list [8] to dict {'Gfg' : 4} and so on.


2 Answers

Something like this could help:

def nested_set(dic, keys, value):     for key in keys[:-1]:         dic = dic.setdefault(key, {})     dic[keys[-1]] = value 

And you can use it like this:

>>> d = {} >>> nested_set(d, ['person', 'address', 'city'], 'New York') >>> d {'person': {'address': {'city': 'New York'}}} 
like image 158
Bakuriu Avatar answered Sep 20 '22 08:09

Bakuriu


I took the freedom to extend the code from the answer of Bakuriu. Therefore upvotes on this are optional, as his code is in and of itself a witty solution, which I wouldn't have thought of.

def nested_set(dic, keys, value, create_missing=True):     d = dic     for key in keys[:-1]:         if key in d:             d = d[key]         elif create_missing:             d = d.setdefault(key, {})         else:             return dic     if keys[-1] in d or create_missing:         d[keys[-1]] = value     return dic 

When setting create_missing to True, you're making sure to only set already existing values:

# Trying to set a value of a nonexistent key DOES NOT create a new value print(nested_set({"A": {"B": 1}}, ["A", "8"], 2, False)) >>> {'A': {'B': 1}}  # Trying to set a value of an existent key DOES create a new value print(nested_set({"A": {"B": 1}}, ["A", "8"], 2, True)) >>> {'A': {'B': 1, '8': 2}}  # Set the value of an existing key print(nested_set({"A": {"B": 1}}, ["A", "B"], 2)) >>> {'A': {'B': 2}} 
like image 36
JackLeEmmerdeur Avatar answered Sep 21 '22 08:09

JackLeEmmerdeur