Python | Convert flattened dictionary into nested dictionary
Last Updated :
10 Apr, 2023
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 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.
- 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.
- 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.
- 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.
- The convert_nested() function then iterates over each list in the lists iterator and inserts it into the result dictionary using the insert() function.
- Finally, the convert_nested() function returns the resulting nested dictionary result.
- Define an initial dictionary named ini_dict containing key-value pairs.
- Print the initial dictionary using the print() function.
- 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.
- 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
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):
result = dict ()
lists = ([ * k.split( "_" ), v] for k, v in dct.items())
for lst in lists:
insert(result, lst)
return result
ini_dict = { 'Geeks_for_for' : 1 , 'Geeks_for_geeks' : 4 ,
'for_geeks_Geeks' : 3 , 'geeks_Geeks_for' : 7 }
print ( "initial_dictionary" , str (ini_dict))
_split_dict = [[ * a.split( '_' ), b] for a, b in ini_dict.items()]
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
def nest_dict(dict1):
result = {}
for k, v in dict1.items():
split_rec(k, v, result)
return result
def split_rec(k, v, out):
k, * rest = k.split( '_' , 1 )
if rest:
split_rec(rest[ 0 ], v, out.setdefault(k, {}))
else :
out[k] = v
ini_dict = { 'Geeks_for_for' : 1 , 'Geeks_for_geeks' : 4 ,
'for_geeks_Geeks' : 3 , 'geeks_Geeks_for' : 7 }
print ( "initial_dictionary" , str (ini_dict))
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
from collections import defaultdict
from functools import reduce
from operator import getitem
def getFromDict(dataDict, mapList):
return reduce (getitem, mapList, dataDict)
tree = lambda : defaultdict(tree)
d = tree()
def default_to_regular(d):
if isinstance (d, defaultdict):
d = {k: default_to_regular(v) for k, v in d.items()}
return d
ini_dict = { 'Geeks_for_for' : 1 , 'Geeks_for_geeks' : 4 ,
'for_geeks_Geeks' : 3 , 'geeks_Geeks_for' : 7 }
print ( "initial_dictionary" , str (ini_dict))
for k, v in ini_dict.items():
* keys, final_key = k.split( '_' )
getFromDict(d, keys)[final_key] = v
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 :
- 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.
- 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.
- 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.
- 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.
- Create an empty dictionary d that will hold the nested dictionary.
- Iterate over the flattened dictionary ini_dict using a for loop.
- Split each key in ini_dict into a list of keys using the split method.
- Call the add_to_nested_dict function with the empty dictionary d, the list of keys, and the value.
- Print the final nested dictionary d.
Python3
def add_to_nested_dict(nested_dict, keys, value):
if len (keys) = = 1 :
nested_dict[keys[ 0 ]] = value
else :
if keys[ 0 ] not in nested_dict:
nested_dict[keys[ 0 ]] = {}
add_to_nested_dict(nested_dict[keys[ 0 ]], keys[ 1 :], value)
ini_dict = { 'Geeks_for_for' : 1 , 'Geeks_for_geeks' : 4 ,
'for_geeks_Geeks' : 3 , 'geeks_Geeks_for' : 7 }
print ( "initial_dictionary" , str (ini_dict))
d = {}
for k, v in ini_dict.items():
keys = k.split( '_' )
add_to_nested_dict(d, keys, v)
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
- Create an empty dictionary.
- Iterate through the items in the initial dictionary using a for loop.
- Split the keys into a list using the split() method and store the value in a variable.
- Create a variable temp that references the empty dictionary.
- Iterate through the list of keys using a for loop.
- If the key exists in temp, update temp to reference the value of that key.
- 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.
- 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.
- Return the nested dictionary.
Python3
def add_to_nested_dict(nested_dict, keys, value):
temp = nested_dict
for key in keys[: - 1 ]:
temp = temp.setdefault(key, {})
temp[keys[ - 1 ]] = value
return nested_dict
ini_dict = { 'Geeks_for_for' : 1 , 'Geeks_for_geeks' : 4 ,
'for_geeks_Geeks' : 3 , 'geeks_Geeks_for' : 7 }
print ( "initial_dictionary" , str (ini_dict))
d = {}
for k, v in ini_dict.items():
keys = k.split( '_' )
add_to_nested_dict(d, keys, v)
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.
Similar Reads
Python - Convert Nested Dictionary into Flattened Dictionary
We are given a nested dictionary we need to flatten the dictionary into single dictionary. For example, we are given a nested dictionary a = {'a': 1, 'b': {'x': 2, 'y': {'z': 3}}, 'c': {'m': 4} } we need to flatten the dictionary so that output becomes {'a': 1, 'c_m': 4, 'b_x': 2, 'b_y_z': 3}. We ca
3 min read
Python - Convert Flat dictionaries to Nested dictionary
Sometimes, while working with records, we can have a problem in which we need to perform the task of conversion of multiple flat dictionaries to a single nested dictionary. This can have applications in many domains in which data is used extensively. Let's discuss certain ways by which we can conver
4 min read
Convert Nested Dictionary to List in Python
In this article, weâll explore several methods to Convert Nested Dictionaries to a List in Python. List comprehension is the fastest and most concise way to convert a nested dictionary into a list. [GFGTABS] Python a = { "a": {"x": 1, "y": 2}, "b": {"x
3 min read
Convert Dictionary Value list to Dictionary List Python
Sometimes, while working with Python Dictionaries, we can have a problem in which we need to convert dictionary list to nested records dictionary taking each index of dictionary list value and flattening it. This kind of problem can have application in many domains. Let's discuss certain ways in whi
9 min read
Python - Convert Dictionaries List to Order Key Nested dictionaries
Given list of dictionaries, our task is to convert a list of dictionaries into a dictionary where each key corresponds to the index of the dictionary in the list and the value is the dictionary itself. For example: consider this list of dictionaries: li = [{"Gfg": 3, 4: 9}, {"is": 8, "Good": 2}] the
3 min read
Convert List of Dictionaries to Dictionary of Lists - Python
We are given a list of dictionaries we need to convert it to dictionaries of lists. For example, we are given a list of dictionaries li = [{'manoj': 'java', 'bobby': 'python'}, {'manoj': 'php', 'bobby': 'java'}, {'manoj': 'cloud', 'bobby': 'big-data'}] we need to convert this to dictionary of list s
3 min read
Convert String Dictionary to Dictionary Python
The goal here is to convert a string that represents a dictionary into an actual Python dictionary object. For example, you might have a string like "{'a': 1, 'b': 2}" and want to convert it into the Python dictionary {'a': 1, 'b': 2}. Let's understand the different methods to do this efficiently. U
2 min read
Python - Convert list of dictionaries to Dictionary Value list
We are given a list of dictionaries we need to convert it to dictionary. For example, given a list of dictionaries: d = [{'a': 1, 'b': 2}, {'a': 3, 'b': 4}, {'a': 5, 'b': 6}], the output should be: {'a': [1, 3, 5], 'b': [2, 4, 6]}. Using Dictionary ComprehensionUsing dictionary comprehension, we can
3 min read
Remove Duplicate Dictionaries from Nested Dictionary - Python
We are given a nested dictionary we need to remove the duplicate dictionaries from the nested dictionary. For example we are given a nested dictionary d = {'key1': [{'a': 1}, {'b': 2}, {'a': 1}], 'key2': [{'x': 3}, {'y': 4}]} we need to remove the duplicate dictionary from this dictionary so output
4 min read
Python - Conditional Join Dictionary List
Given 2 dictionaries list, the task is to write a Python program to perform conditional join i.e add keys, based upon similarity of particular key in similar index dictionary. Example: Input : test_list1 = [{"gfg" : 1, "is" : 3, "best": 2}, {"gfg" : 1, "best" : 6}, {"all" : 7, "best" : 10} ],test_li
8 min read