Python: Update Nested Dictionary
Last Updated :
14 May, 2020
A Dictionary in Python works similar to the Dictionary in the real world. Keys of a Dictionary must be unique and of immutable data types such as Strings, Integers, and tuples, but the key-values can be repeated and be of any type.
Refer to the below article to get the idea about dictionaries:
Nested Dictionary: The nested dictionaries in Python are nothing but dictionaries within a dictionary.
Consider an employee record as given below :
Employees
emp1:
name:Lisa
age:29
designation:Programmer
emp2:
name:Steve
age:45
designation:HR
Here, the employees is the outer dictionary. emp1, emp2 are keys that have another dictionary as their value. The dictionary structure of the above information appears as :
employees:
{
emp1:
{
'name':'Lisa',
'age':29,
'designation':'Programmer'
},
emp2:
{
'name':'Steve',
'age':45,
'designation':'HR'
}
}
Consider a simple dictionary like d={'a':1, 'b':2, 'c':3}
. If you want to update the value of ‘b’ to 7, you can write as d['b']=7
. However the same method cannot be applied to nested ones. That will create a new key as the keys in outer dictionary will only be searched while you try to update. For example, see the code below:
Employee = {
'emp1' : {
'name' : 'Lisa' ,
'age' : '29' ,
'Designation' : 'Programmer'
},
'emp2' : {
'name' : 'Steve' ,
'age' : '45' ,
'Designation' : 'HR'
}
}
Employee[ 'name' ] = 'Kate'
print (Employee)
|
Output:
{‘name’: ‘Kate’, ’emp1′: {‘Designation’: ‘Programmer’, ‘name’: ‘Lisa’, ‘age’: ’29’}, ’emp2′: {‘Designation’: ‘HR’, ‘name’: ‘Steve’, ‘age’: ’45’}}
In the output look that ‘name’:’Kate’ is added as a new key-value pair which is not our desired output. Let us consider that we need to update first employee’s name as ‘Kate’. Let us look at our dictionary as a 2D-array. This will help us update the information easily. The 2D-array view of the above dictionary is given below:
Employee name age Designation
emp1 Lisa 29 Programmer
emp2 Steve 45 HR
Now we have to update the first employee’s name as ‘Kate’. So we have to update Employee[’emp1′][‘name’]. The modified code is given below:
Employee = {
'emp1' : {
'name' : 'Lisa' ,
'age' : '29' ,
'Designation' : 'Programmer'
},
'emp2' : {
'name' : 'Steve' ,
'age' : '25' ,
'Designation' : 'HR'
}
}
Employee[ 'emp1' ][ 'name' ] = 'Kate'
print (Employee)
|
Output:
{’emp2′: {‘Designation’: ‘HR’, ‘age’: ’25’, ‘name’: ‘Steve’}, ’emp1′: {‘Designation’: ‘Programmer’, ‘age’: ’29’, ‘name’: ‘Kate’}}
The above method updates the value for the mentioned key if it is present in the dictionary. Otherwise, it creates a new entry. For example if you want to add a new attribute ‘salary’ for the first employee, then you can write the above code as :
Employee = {
'emp1' : {
'name' : 'Lisa' ,
'age' : '29' ,
'Designation' : 'Programmer'
},
'emp2' : {
'name' : 'Steve' ,
'age' : '25' ,
'Designation' : 'HR'
}
}
Employee[ 'emp1' ][ 'name' ] = 'Kate'
Employee[ 'emp1' ][ 'salary' ] = 56000
print (Employee)
|
Output:
{’emp1′: {‘Designation’: ‘Programmer’, ‘salary’: 56000, ‘name’: ‘Kate’, ‘age’: ’29’}, ’emp2′: {‘Designation’: ‘HR’, ‘name’: ‘Steve’, ‘age’: ’25’}}
The above methods are static. Now to make it interactive with the user, we can slightly modify the code as given below:
Employee = {
'emp1' : {
'name' : 'Lisa' ,
'age' : '29' ,
'Designation' : 'Programmer'
},
'emp2' : {
'name' : 'Steve' ,
'age' : '25' ,
'Designation' : 'HR'
}
}
empid = input ( "Employee id :" )
attribute = input ( "Attribute to be updated :" )
new_value = input ( "New value :" )
Employee[empid][attribute] = new_value
print (Employee)
|
Input:
Employee id :emp1
Attribute to be updated :name
New value :Kate
Output:
{’emp1′: {‘age’: ’29’, ‘Designation’: ‘Programmer’, ‘name’: ‘Kate’}, ’emp2′: {‘age’: ’25’, ‘Designation’: ‘HR’, ‘name’: ‘Steve’}}
Let us try to be a bit more professional!!
An alternative approach
The idea is to flatten the nested dictionary first, then update it and unflatten it again. To make it more clear, consider the following dictionary as an example:
dict1={
'a':{
'b':1
},
'c':{
'd':2,
'e':5
}
}
Flattening a nested dictionary is nothing but appending the parent key with the real key using appropriate separators. The separator can be any symbol. It can be a comma(, ), or a hyphen(-), or an underscore(_), or a period(.), or even just a space( ). Here, after flattening with underscore as the separator, this dictionary will look like :
dict1={'a_b':1, 'c_d':2, 'c_e':5}
The flattening can be easily done with the in-built methods provided by the package flatten-dict
in Python. It provides methods for flattening dictionary like objects and unflattening them. Install the package using the pip command as below:
pip install flatten-dict
flatten()
method:
The flatten method has various arguments to format it in a desirable, readable and understandable way. The two most important arguments among all is:
- dict : The flattened dictionary which has to be converted
- reducer : It specifies how the parent key is joined with the child. The values possible are tuple, path, underscore or a user defined function name.
- tuple: creates a tuple of parent and child keys as the key and assigns the value to it.
- path : Appends ‘/’ between the parent and child key.
- underscore: Appends ‘_’ between the parent and child key.
- User defined function: The parent and child key should be passed to the function as arguments. The function should return them as a string separated by desired symbol
Other arguments enumerate_types, keep_empty_types are optional
unflatten() method:
This method unflattens the flattened dictionary and converts it into a nested one. It can take three arguments :
- dict : The flattened dictionary which has to be reverted
- splitter : The symbol on which the flattened dictionary has to be split. Like flatten method, this also takes up the value tuple, path, underscore or a user defined function.
- inverse : Takes a boolean value indicating whether key and value has to be inverted. This is optional.
Let us consider the same Employee example we tried above. The code is given below:
from flatten_dict import flatten
from flatten_dict import unflatten
Employee = {
'emp1' : {
'name' : 'Lisa' ,
'age' : '29' ,
'Designation' : 'Programmer'
},
'emp2' : {
'name' : 'Steve' ,
'age' : '25' ,
'Designation' : 'HR'
}
}
dict3 = flatten(Employee)
print ( "Flattened dictionary :" , dict3)
dict3[( 'emp2' , 'salary' )] = 34000
print (dict3)
Employee = unflatten(dict3)
print ( "\nUnflattened and updated dictionary :" , Employee)
|
Output:
Flattened dictionary : {(’emp1′, ‘name’): ‘Lisa’, (’emp1′, ‘age’): ’29’, (’emp1′, ‘Designation’): ‘Programmer’, (’emp2′, ‘name’): ‘Steve’, (’emp2′, ‘age’): ’25’, (’emp2′, ‘Designation’): ‘HR’}
{(’emp1′, ‘name’): ‘Lisa’, (’emp1′, ‘age’): ’29’, (’emp1′, ‘Designation’): ‘Programmer’, (’emp2′, ‘name’): ‘Steve’, (’emp2′, ‘age’): ’25’, (’emp2′, ‘Designation’): ‘HR’, (’emp2′, ‘salary’): 34000}
Unflattened and updated dictionary : {’emp1′: {‘name’: ‘Lisa’, ‘age’: ’29’, ‘Designation’: ‘Programmer’}, ’emp2′: {‘name’: ‘Steve’, ‘age’: ’25’, ‘Designation’: ‘HR’, ‘salary’: 34000}}
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...