Open In App

Python | Convert nested dictionary into flattened dictionary

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

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 :

  1. The function checks if the input dd is a dictionary. If it is, then it iterates over each key-value pair in the dictionary, and calls the flatten_dict function recursively on the value of each key. It concatenates the original key and the returned key from the recursive call with the separator, and uses that as the new key in the flattened dictionary. It sets the value of the new key to the returned value from the recursive call.
  2. If the input dd is not a dictionary, the function creates a new dictionary with a single key-value pair, where the key is the prefix argument (which is the path to the current value in the original nested dictionary), and the value is the input dd itself.
  3. The code then initializes a nested dictionary ini_dict with some sample data.
  4. The code prints the initial dictionary ini_dict.
  5. The code calls the flatten_dict function on the ini_dict dictionary and prints the resulting flattened dictionary.

Python3




# Python code to demonstrate
# conversion of nested dictionary
# into flattened dictionary
 
# code to convert ini_dict to flattened dictionary
# default separator '_'
def flatten_dict(dd, separator ='_', prefix =''):
    return { prefix + separator + k if prefix else k : v
             for kk, vv in dd.items()
             for k, v in flatten_dict(vv, separator, kk).items()
             } if isinstance(dd, dict) else { prefix : dd }
         
# initialising_dictionary
ini_dict = {'geeks': {'Geeks': {'for': 7}},
            'for': {'geeks': {'Geeks': 3}},
            'Geeks': {'for': {'for': 1, 'geeks': 4}}}
 
# printing initial dictionary
print ("initial_dictionary", str(ini_dict))
 
 
# printing final dictionary
print ("final_dictionary", str(flatten_dict(ini_dict)))


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

Time complexity: O(n^2), where n is the total number of keys in the nested dictionary.
Auxiliary space: O(n), where n is the total number of keys in the nested dictionary. The auxiliary space is used to store the result of the flatten dictionary in the form of a new dictionary.

Method #2: Using mutableMapping 

Python3




# Python code to demonstrate
# conversion of nested dictionary
# into flattened dictionary
 
from collections import MutableMapping
 
# code to convert ini_dict to flattened dictionary
# default separator '_'
def convert_flatten(d, parent_key ='', sep ='_'):
    items = []
    for k, v in d.items():
        new_key = parent_key + sep + k if parent_key else k
 
        if isinstance(v, MutableMapping):
            items.extend(convert_flatten(v, new_key, sep = sep).items())
        else:
            items.append((new_key, v))
    return dict(items)
         
# initialising_dictionary
ini_dict = {'geeks': {'Geeks': {'for': 7}},
            'for': {'geeks': {'Geeks': 3}},
            'Geeks': {'for': {'for': 1, 'geeks': 4}}}
 
# printing initial dictionary
print ("initial_dictionary", str(ini_dict))
 
 
# printing final dictionary
print ("final_dictionary", str(convert_flatten(ini_dict)))


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

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

Method #3: Using Python Generators  

Python3




# Python code to demonstrate
# conversion of nested dictionary
# into flattened dictionary
 
my_map = {"a" : 1,
        "b" : {
            "c": 2,
            "d": 3,
            "e": {
                "f":4,
                6:"a",
                5:{"g" : 6},
                "l":[1,"two"]
            }
        }}
 
# Expected Output
# {'a': 1, 'b_c': 2, 'b_d': 3, 'b_e_f': 4, 'b_e_6': 'a', 'b_e_5_g': 6, 'b_e_l': [1, 'two']}
 
 
ini_dict = {'geeks': {'Geeks': {'for': 7}},
            'for': {'geeks': {'Geeks': 3}},
            'Geeks': {'for': {'for': 1, 'geeks': 4}}}
 
# Expected Output
# {‘Geeks_for_geeks’: 4, ‘for_geeks_Geeks’: 3, ‘Geeks_for_for’: 1, ‘geeks_Geeks_for’: 7}
 
def flatten_dict(pyobj, keystring=''):
    if type(pyobj) == dict:
        keystring = keystring + '_' if keystring else keystring
        for k in pyobj:
            yield from flatten_dict(pyobj[k], keystring + str(k))
    else:
        yield keystring, pyobj
 
print("Input : %s\nOutput : %s\n\n" %
     (my_map, { k:v for k,v in flatten_dict(my_map) }))
 
print("Input : %s\nOutput : %s\n\n" %
     (ini_dict, { k:v for k,v in flatten_dict(ini_dict) }))


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

Time complexity: O(n), where n is the total number of keys in the nested dictionary
Auxiliary space: O(n), where n is the total number of keys in the nested dictionary. 

Method #4: Using recursion and a separator

  1. Define a function “flatten_dict” that takes in three parameters: dd (a dictionary), separator (a string, default value “_”), and prefix (a string, default value “”).
  2. Initialize an empty dictionary “res”.
  3. Iterate through each key-value pair in the dictionary “dd”.
  4. Check if the value associated with the current key is itself a dictionary or not. If it is a dictionary, then recursively call the “flatten_dict” function with the value as the new dictionary to be flattened, the separator and prefix updated with the current key and separator value.
  5. If the value is not a dictionary, then add the key-value pair to the “res” dictionary, where the key is the concatenation of prefix, separator and current key.
  6. Return the final “res” dictionary.

Python3




# code to convert ini_dict to flattened dictionary
def flatten_dict(dd, separator='_', prefix=''):
    res = {}
    for key, value in dd.items():
        if isinstance(value, dict):
            res.update(flatten_dict(value, separator, prefix + key + separator))
        else:
            res[prefix + key] = value
    return res
 
# initialising_dictionary
ini_dict = {'geeks': {'Geeks': {'for': 7}},
            'for': {'geeks': {'Geeks': 3}},
            'Geeks': {'for': {'for': 1, 'geeks': 4}}}
 
# printing initial dictionary
print("initial dictionary", str(ini_dict))
 
# flattening the dictionary
res = flatten_dict(ini_dict)
 
# printing final dictionary
print("final dictionary", str(res))
#This code is contributed by Vinay Pinjala.


Output

initial dictionary {'geeks': {'Geeks': {'for': 7}}, 'for': {'geeks': {'Geeks': 3}}, 'Geeks': {'for': {'for': 1, 'geeks': 4}}}
final dictionary {'geeks_Geeks_for': 7, 'for_geeks_Geeks': 3, 'Geeks_for_for': 1, 'Geeks_for_geeks': 4}

The time complexity of this algorithm is O(N), where N is the total number of keys in the nested dictionary. This is because the algorithm iterates through each key exactly once.
The space complexity is also O(N), where N is the total number of keys, since the algorithm creates a new dictionary “res” to store the flattened dictionary.

Method 5: Using a stack data structure

The idea is to iterate through the dictionary and push all nested dictionaries into a stack. Then, we can pop each dictionary from the stack, iterate through its key-value pairs, and append the key-value pairs to a flattened dictionary.

  1. Initialize an empty stack.
  2. Push the initial dictionary onto the stack.
  3. Initialize an empty flattened dictionary.
  4. While the stack is not empty, do the following:
    a. Pop the top dictionary from the stack.
    b. For each key-value pair in the popped dictionary, do the following:
    i. If the value is a dictionary, push it onto the stack with its key as the prefix.
    ii. Otherwise, add the key-value pair to the flattened dictionary with the prefix and separator (default is ‘_’).
  5. Return the flattened dictionary.

Python3




# code to convert ini_dict to flattened dictionary using stack data structure
def flatten_dict(dd, separator='_', prefix=''):
    stack = [(dd, prefix)]
    flat_dict = {}
     
    while stack:
        cur_dict, cur_prefix = stack.pop()
        for key, val in cur_dict.items():
            new_key = cur_prefix + separator + key if cur_prefix else key
            if isinstance(val, dict):
                stack.append((val, new_key))
            else:
                flat_dict[new_key] = val
                 
    return flat_dict
 
# initialising_dictionary
ini_dict = {'geeks': {'Geeks': {'for': 7}},
            'for': {'geeks': {'Geeks': 3}},
            'Geeks': {'for': {'for': 1, 'geeks': 4}}}
 
# printing initial dictionary
print("initial_dictionary", str(ini_dict))
 
# printing final dictionary
print("final_dictionary", str(flatten_dict(ini_dict)))


Output

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

Time complexity: O(n), where n is the total number of key-value pairs in the input nested dictionary.
Auxiliary space: O(n), where n is the total number of key-value pairs in the input nested dictionary.

Method 6: Using a recursive function without a separator

Here is an alternative method that uses a recursive function without a separator. It works by iterating over the items of the dictionary and checking whether each value is another dictionary. If it is, the function calls itself recursively and concatenates the key with the new keys returned by the recursive call. If it is not, the function simply adds the key-value pair to the result dictionary.

Here’s the step by step approach:

  1. Define a function called flatten_dict_recursive that takes a dictionary d as input.
  2. Initialize an empty dictionary called result.
  3. For each key-value pair in d, do the following:
    a. If the value is a dictionary, call flatten_dict_recursive with the value and concatenate the returned keys with the current key.
    b. If the value is not a dictionary, add the current key and value to result.
  4. Return result.

Python3




def flatten_dict(dd, separator='_', prefix=''):
    stack = [(dd, prefix)]
    flat_dict = {}
     
    while stack:
        cur_dict, cur_prefix = stack.pop()
        for key, val in cur_dict.items():
            new_key = cur_prefix + separator + key if cur_prefix else key
            if isinstance(val, dict):
                stack.append((val, new_key))
            else:
                flat_dict[new_key] = val
                 
    return flat_dict
 
# initialising_dictionary
ini_dict = {'geeks': {'Geeks': {'for': 7}},
            'for': {'geeks': {'Geeks': 3}},
            'Geeks': {'for': {'for': 1, 'geeks': 4}}}
 
# printing initial dictionary
print("initial_dictionary", str(ini_dict))
 
# printing final dictionary
print("final_dictionary", str(flatten_dict(ini_dict, separator='')))


Output

initial_dictionary {'geeks': {'Geeks': {'for': 7}}, 'for': {'geeks': {'Geeks': 3}}, 'Geeks': {'for': {'for': 1, 'geeks': 4}}}
final_dictionary {'Geeksforfor': 1, 'Geeksforgeeks': 4, 'forgeeksGeeks': 3, 'geeksGeeksfor': 7}

Time complexity: The time complexity of this function is O(n), where n is the total number of key-value pairs in the dictionary. 

Auxiliary space: The auxiliary space complexity of this function is O(n), where n is the total number of key-value pairs in the dictionary. 



Similar Reads

Python | Convert flattened dictionary into nested dictionary
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 : Define a function named insert that takes two parameters, a dictionary (dct) and a list (lst). This functi
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
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
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 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