Saturday, November 16, 2024
Google search engine
HomeLanguagesPython: Update Nested Dictionary

Python: Update Nested Dictionary

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.

python-nested-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:




# an employee record
Employee =
    'emp1': {
        'name': 'Lisa'
        'age': '29',
        'Designation':'Programmer'
            }, 
    'emp2': {
             'name': 'Steve',
             'age': '45',
             'Designation':'HR'
             }
  
# updating in the way similar to
# simple dictionary
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:




# an employee record
Employee =
    'emp1': {
        'name': 'Lisa'
        'age': '29',
        'Designation':'Programmer'
            }, 
         'emp2': {
             'name': 'Steve',
             'age': '25',
             'Designation':'HR'
                 }
             
  
# updating in the way similar to simple dictionary
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 :




# an employee record
Employee =
    'emp1': {
        'name': 'Lisa'
        'age': '29',
        'Designation':'Programmer'
            }, 
         'emp2': {
             'name': 'Steve',
             'age': '25',
             'Designation':'HR'
                 }
             
  
# updating in the way similar to 
# simple dictionary
Employee['emp1']['name']='Kate'
  
# adding new key-value pair to first 
# employee record
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:




# an employee record
Employee =
    'emp1': {
        'name': 'Lisa'
        'age': '29',
        'Designation':'Programmer'
            }, 
         'emp2': {
             'name': 'Steve',
             'age': '25',
             'Designation':'HR'
                 }
             
  
# to make the updation dynamic
  
# Get input from the user for which 
# employee he needs to update
empid = input("Employee id :")
  
# which attribute / key to update
attribute = input("Attribute to be updated :")
  
# what value to update
new_value = input("New value :")
  
# updation of the dictionary
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:

  1. dict : The flattened dictionary which has to be converted
  2. 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 :

  1. dict : The flattened dictionary which has to be reverted
  2. 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.
  3. 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
  
# an employee record
Employee =
    'emp1': {
        'name': 'Lisa'
        'age': '29',
        'Designation':'Programmer'
            }, 
         'emp2': {
             'name': 'Steve',
             'age': '25',
             'Designation':'HR'
                 }
             
  
# flattening the dictionary, default 
# reducer is 'tuple'
dict3 = flatten(Employee)
  
print("Flattened dictionary :", dict3)
  
# adding new key-value pair to second 
# employee's record
dict3[('emp2', 'salary')]= 34000
  
print(dict3)
  
# unflattening the dictionary, default 
# splitter is 'tuple'
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}}

RELATED ARTICLES

Most Popular

Recent Comments