Open In App

Python | Convert flattened dictionary into nested dictionary

Last Updated : 10 Apr, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Given a flattened dictionary, the task is to convert that dictionary into a nested dictionary where keys are needed to be split at ‘_’ considering where nested dictionary will be started.

Method #1: Using Naive Approach 

Step-by-step approach :

  1. Define a function named insert that takes two parameters, a dictionary (dct) and a list (lst). This function iterates over all elements of the input list except the last two elements, and creates nested dictionaries corresponding to each element in the list.
  2. The insert() function then updates the dictionary (dct) with a key-value pair where the key is the second last element of the input list, and the value is the last element of the input list.
  3. Define a function named convert_nested that takes a dictionary (dct) as an input. This function first initializes an empty dictionary named result to store the output nested dictionary.
  4. The function then creates an iterator named lists, which is a list of lists where each list represents a hierarchical flow of keys and values from the input dictionary. To create this iterator, it splits each key of the input dictionary by the ‘_’ character and appends the corresponding value to the list.
  5. The convert_nested() function then iterates over each list in the lists iterator and inserts it into the result dictionary using the insert() function.
  6. Finally, the convert_nested() function returns the resulting nested dictionary result.
  7. Define an initial dictionary named ini_dict containing key-value pairs.
  8. Print the initial dictionary using the print() function.
  9. Create a new list named _split_dict that contains lists representing the hierarchical flow of keys and values from the initial dictionary by splitting each key of the dictionary by the ‘_’ character and appending the corresponding value to the list.
  10. Print the final nested dictionary by calling the convert_nested() function on the initial dictionary and print the resulting nested dictionary using the print() function.

Below is the implementation of the above approach:

Python3




# Python code to demonstrate
# conversion of flattened dictionary
# into nested dictionary
 
 
def insert(dct, lst):
    for x in lst[:-2]:
        dct[x] = dct = dct.get(x, dict())
    dct.update({lst[-2]: lst[-1]})
     
 
def convert_nested(dct):
    # empty dict to store the result
    result = dict()
 
    # create an iterator of lists
    # representing nested or hierarchical flow
    lists = ([*k.split("_"), v] for k, v in dct.items())
 
    # insert each list into the result
    for lst in lists:
        insert(result, lst)
    return result
         
# initialising_dictionary
ini_dict = {'Geeks_for_for':1,'Geeks_for_geeks':4,
            'for_geeks_Geeks':3,'geeks_Geeks_for':7}
 
# printing initial dictionary
print ("initial_dictionary", str(ini_dict))
 
# code to convert ini_dict to nested
# dictionary splitting_dict_keys
_split_dict = [[*a.split('_'), b] for a, b in ini_dict.items()]
 
 
# printing final dictionary
print ("final_dictionary", str(convert_nested(ini_dict)))


Output

initial_dictionary {'Geeks_for_for': 1, 'Geeks_for_geeks': 4, 'for_geeks_Geeks': 3, 'geeks_Geeks_for': 7}
final_dictionary {'Geeks': {'for': {'for': 1, 'geeks': 4}}, 'for': {'geeks': {'Geeks': 3}}, 'geeks': {'Geeks': {'for': 7}}}

Time Complexity: O(n)
Auxiliary Space: O(n)

Method #2: Using default dict and recursive approach 

Python3




# Python code to demonstrate
# conversion of flattened dictionary
# into nested dictionary
 
# code to convert dict into nested dict
def nest_dict(dict1):
    result = {}
    for k, v in dict1.items():
         
        # for each key call method split_rec which
        # will split keys to form recursively
        # nested dictionary
        split_rec(k, v, result)
    return result
 
def split_rec(k, v, out):
     
    # splitting keys in dict
    # calling_recursively to break items on '_'
    k, *rest = k.split('_', 1)
    if rest:
        split_rec(rest[0], v, out.setdefault(k, {}))
    else:
        out[k] = v
 
         
# initialising_dictionary
ini_dict = {'Geeks_for_for':1,'Geeks_for_geeks':4,
            'for_geeks_Geeks':3,'geeks_Geeks_for':7}
 
# printing initial dictionary
print ("initial_dictionary", str(ini_dict))
 
# printing final dictionary
print ("final_dictionary", str(nest_dict(ini_dict)))


Output

initial_dictionary {'Geeks_for_for': 1, 'Geeks_for_geeks': 4, 'for_geeks_Geeks': 3, 'geeks_Geeks_for': 7}
final_dictionary {'Geeks': {'for': {'for': 1, 'geeks': 4}}, 'for': {'geeks': {'Geeks': 3}}, 'geeks': {'Geeks': {'for': 7}}}

Time complexity: O(n), where n is the length of the key string.
Auxiliary space: O(N * n), where N is the number of items in the input dictionary and n is the length of the longest key string. 

Method #3: Using reduce and getitem 

Python3




# Python code to demonstrate
# conversion of flattened dictionary
# into nested dictionary
 
from collections import defaultdict
from functools import reduce
from operator import getitem
 
 
def getFromDict(dataDict, mapList):
     
    # Iterate nested dictionary
    return reduce(getitem, mapList, dataDict)
     
# instantiate nested defaultdict of defaultdicts
tree = lambda: defaultdict(tree)
d = tree()
 
# converting default_dict_to regular dict
def default_to_regular(d):
     
    """Convert nested defaultdict to regular dict of dicts."""
    if isinstance(d, defaultdict):
        d = {k: default_to_regular(v) for k, v in d.items()}
    return d
         
# initialising_dictionary
ini_dict = {'Geeks_for_for':1,'Geeks_for_geeks':4,
            'for_geeks_Geeks':3,'geeks_Geeks_for':7}
 
# printing initial dictionary
print ("initial_dictionary", str(ini_dict))
 
 
# code to convert ini_dict to nested dictionary
# iterating_over_dict
for k, v in ini_dict.items():
     
    # splitting keys
    * keys, final_key = k.split('_')
    getFromDict(d, keys)[final_key] = v
 
# printing final dictionary
print ("final_dictionary", str(default_to_regular(d)))


Output

initial_dictionary {'Geeks_for_for': 1, 'Geeks_for_geeks': 4, 'for_geeks_Geeks': 3, 'geeks_Geeks_for': 7}
final_dictionary {'Geeks': {'for': {'for': 1, 'geeks': 4}}, 'for': {'geeks': {'Geeks': 3}}, 'geeks': {'Geeks': {'for': 7}}}

Time complexity: O(n), where n is the number of key-value pairs in the dictionary.
Auxiliary space: O(nm), where n and m are the same as explained above

Method 4 :  Using a recursive function without defaultdict or reduce

uses a recursive function add_to_nested_dict to add values to a nested dictionary. The function takes a nested dictionary, a list of keys, and a value as inputs. If the list of keys has only one key, the function adds the value to the nested dictionary at that key. Otherwise, it creates a nested dictionary at the first key if it doesn’t already exist, and then recursively calls the function with the remaining keys and value.

step-by-step approach :

  1. Create a function add_to_nested_dict that takes three arguments: a nested dictionary, a list of keys, and a value. This function will add the value to the nested dictionary at the specified keys.
  2. Check if the length of the keys list is 1. If it is, add the value to the nested dictionary at the last key in the list.
  3. If the length of the keys list is greater than 1, check if the first key is in the nested dictionary. If it isn’t, create a new nested dictionary at that key.
  4. Recursively call the add_to_nested_dict function with the nested dictionary at the first key in the list, the remaining keys in the list, and the value.
  5. Create an empty dictionary d that will hold the nested dictionary.
  6. Iterate over the flattened dictionary ini_dict using a for loop.
  7. Split each key in ini_dict into a list of keys using the split method.
  8. Call the add_to_nested_dict function with the empty dictionary d, the list of keys, and the value.
  9. Print the final nested dictionary d.

Python3




def add_to_nested_dict(nested_dict, keys, value):
    """Add a value to a nested dictionary at the specified keys."""
    if len(keys) == 1:
        # base case: add value to the last key in the list
        nested_dict[keys[0]] = value
    else:
        # recursive case: create nested dictionary if it doesn't exist
        if keys[0] not in nested_dict:
            nested_dict[keys[0]] = {}
        # recursively call function with remaining keys and value
        add_to_nested_dict(nested_dict[keys[0]], keys[1:], value)
 
# initialising_dictionary
ini_dict = {'Geeks_for_for':1,'Geeks_for_geeks':4,
            'for_geeks_Geeks':3,'geeks_Geeks_for':7}
 
# printing initial dictionary
print ("initial_dictionary", str(ini_dict))
 
# create empty nested dictionary
d = {}
 
# iterating_over_dict
for k, v in ini_dict.items():
    # splitting keys
    keys = k.split('_')
    # add value to nested dictionary
    add_to_nested_dict(d, keys, v)
 
# printing final dictionary
print ("final_dictionary", str(d))


Output

initial_dictionary {'Geeks_for_for': 1, 'Geeks_for_geeks': 4, 'for_geeks_Geeks': 3, 'geeks_Geeks_for': 7}
final_dictionary {'Geeks': {'for': {'for': 1, 'geeks': 4}}, 'for': {'geeks': {'Geeks': 3}}, 'geeks': {'Geeks': {'for': 7}}}

The time complexity of this approach is O(nm), where n is the number of keys in the flattened dictionary and m is the maximum depth of the nested dictionary. 

The auxiliary space is also O(nm), since the function creates nested dictionaries as needed.

Method 5: Using a loop to iterate through the list of keys

  1. Create an empty dictionary.
  2. Iterate through the items in the initial dictionary using a for loop.
  3. Split the keys into a list using the split() method and store the value in a variable.
  4. Create a variable temp that references the empty dictionary.
  5. Iterate through the list of keys using a for loop.
  6. If the key exists in temp, update temp to reference the value of that key.
  7. If the key does not exist in temp, create a new key with an empty dictionary as its value and update temp to reference that value.
  8. When the loop through the keys is finished, set the final value of the last key in the list to be the value from the initial dictionary.
  9. Return the nested dictionary.

Python3




def add_to_nested_dict(nested_dict, keys, value):
    """Add a value to a nested dictionary at the specified keys."""
    temp = nested_dict
    for key in keys[:-1]:
        temp = temp.setdefault(key, {})
    temp[keys[-1]] = value
    return nested_dict
 
# initialising_dictionary
ini_dict = {'Geeks_for_for':1,'Geeks_for_geeks':4,
            'for_geeks_Geeks':3,'geeks_Geeks_for':7}
 
# printing initial dictionary
print ("initial_dictionary", str(ini_dict))
 
# create empty nested dictionary
d = {}
 
# iterating_over_dict
for k, v in ini_dict.items():
    # splitting keys
    keys = k.split('_')
    # add value to nested dictionary
    add_to_nested_dict(d, keys, v)
 
# printing final dictionary
print ("final_dictionary", str(d))


Output

initial_dictionary {'Geeks_for_for': 1, 'Geeks_for_geeks': 4, 'for_geeks_Geeks': 3, 'geeks_Geeks_for': 7}
final_dictionary {'Geeks': {'for': {'for': 1, 'geeks': 4}}, 'for': {'geeks': {'Geeks': 3}}, 'geeks': {'Geeks': {'for': 7}}}

Time complexity: O(n*m), where n is the number of items in the initial dictionary and m is the maximum number of keys in a single item.
Auxiliary space: O(m), where m is the maximum number of keys in a single item.



Previous Article
Next Article

Similar Reads

Python | Convert nested dictionary into flattened dictionary
Given a nested dictionary, the task is to convert this dictionary into a flattened dictionary where the key is separated by '_' in case of the nested key to be started. Method #1: Using Naive Approach Step-by-step approach : The function checks if the input dd is a dictionary. If it is, then it iterates over each key-value pair in the dictionary, a
8 min read
Why does a nested loop perform much faster than the flattened one?
Python provides three ways for executing the loops. While all the ways provide similar basic functionality, they differ in their syntax and condition checking time. In this article, we will see why does a nested loop performs better than the flattened one. But first, let's see what is a nested loop and what is a flattened loop.4 A nested loop perfo
5 min read
Create a contiguous flattened NumPy array
Let us see how to create a contiguous array in NumPy.The contiguous flattened array is a two-dimensional and multi-dimensional array that is stored as a one-dimensional array. We will be using the ravel() method to perform this task. Syntax : numpy.ravel(array, order = 'C') Parameters : array : Input array. order : C-contiguous, F-contiguous, A-con
2 min read
Compute the median of the flattened NumPy array
In this article, we will discuss how to compute the median of the flattened array. Median is basically that value that separates the lower half of the array with the higher half of array. Example: If there are odd numbers in an array. A = [1,2,3,4,5,6,7] Then the median element will be 7+1/2= 4th element of the array. Hence the Median in this array
2 min read
PyCairo - How we can copy flattened path?
In this article we will learn how we can copy flattened path of object using PyCairo in python. This function is like copy_path() method except that any curves in the path will be approximated with piecewise-linear approximations. PyCairo : Pycairo is a Python module providing bindings for the cairo graphics library.This library is used for creatin
3 min read
Python | Convert list of nested dictionary into Pandas dataframe
Given a list of the nested dictionary, write a Python program to create a Pandas dataframe using it. We can convert list of nested dictionary into Pandas DataFrame. Let's understand the stepwise procedure to create a Pandas Dataframe using the list of nested dictionary. Convert Nested List of Dictionary into Pandas DataframeBelow are the methods th
4 min read
Python | Convert nested sublist into tuples
Sometimes, while working with huge amount of data, we might have in which each point of data constitutes of several elements and needs to be processed as single unit. For this, we might sometimes, just receive a matrix and it's constituent data points are also lists, which don't make much sense and whole and might be required to be converted to tup
8 min read
Python | Convert given list into nested list
Sometimes, we come across data that is in string format in a list and it is required to convert it into a list of the list. This kind of problem of converting a list of strings to a nested list is quite common in web development. Let's discuss certain ways in which this can be performed. Convert the Given List into Nested List in PythonBelow are th
5 min read
Python - Convert Nested Tuple to Custom Key Dictionary
Sometimes, while working with Python records, we can have data that come without proper column names/identifiers, which can just be identified by their index, but we intend to assign them keys and render in form of dictionaries. This kind of problem can have applications in domains such as web development. Let's discuss certain ways in which this t
4 min read
Python - Convert Nested dictionary to Mapped Tuple
Sometimes, while working with Python dictionaries, we can have a problem in which we need to convert nested dictionaries to mapped tuple. This kind of problem can occur in web development and day-day programming. Let's discuss certain ways in which this task can be performed. Input : test_dict = {'gfg' : {'x' : 5, 'y' : 6, 'z': 3}, 'best' : {'x' :
4 min read