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:
Outputinitial_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
Outputinitial_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
Outputinitial_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.
Outputinitial_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.
Outputinitial_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.