Open In App

Python – Flatten and remove keys from Dictionary

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

Given a dictionary, perform flattening and removal of certain dictionary keys.

Input : test_dict = {‘a’: 14, ‘b’: 16, ‘c’: {‘d’: {‘e’: 7}}}, rem_keys = [“c”, “a”, “d”] 
Output : {‘b’: 16, ‘e’: 7} 
Explanation : All “c”, “a” and “d” has been removed.
Input : test_dict = {‘a’: 14, ‘b’: 16, ‘c’: {‘d’: {‘e’: 7}}}, rem_keys = [“c”, “d”, “e”] 
Output : {‘a’: 14, ‘b’: 16} 
Explanation : All “c”, “e” and “d” has been removed. 
 

Method 1: Using recursion + isinstance() + loop

The combination of the above functions can be used to solve this problem. In this, we check for the dictionary as instance for nested dictionary using isinstance() and recur each time for the inner dictionary. The loop is used to iterate for keys.

Python3




# Python3 code to demonstrate working of
# Flatten and remove keys from Dictionary
# Using loop + recursion + isinstance()
 
# function to compute removal and flattening
 
 
def hlper_fnc(test_dict, rem_keys):
    if not isinstance(test_dict, dict):
        return test_dict
    res = {}
 
    for key, val in test_dict.items():
        rem = hlper_fnc(val, rem_keys)
 
        # performing removal
        if key not in rem_keys:
            res[key] = rem
        else:
            if isinstance(rem, dict):
                res.update(rem)
    return res
 
 
# initializing dictionary
test_dict = {'a': 14, 'b': 16, 'c': {'d': {'e': 7}}}
 
# printing original dictionary
print("The original dictionary is : " + str(test_dict))
 
# initializing removal keys
rem_keys = ["c", "d"]
 
# calling helper function for task
res = hlper_fnc(test_dict, rem_keys)
 
# printing result
print("The removed and flattened dictionary : " + str(res))


Output

The original dictionary is : {'a': 14, 'b': 16, 'c': {'d': {'e': 7}}}
The removed and flattened dictionary : {'a': 14, 'b': 16, 'e': 7}

Time complexity of this function is O(n), where n is the total number of elements in the dictionary.
Auxiliary space used by this function is also O(n), where n is the total number of elements in the dictionary. 

The given program uses a recursive approach with a loop and isinstance() function to flatten and remove keys from a nested dictionary. Here is an alternative approach:

Method 2: Using Dictionary Comprehension and Recursion:

The program removes specified keys and flattens a nested dictionary using a recursive approach with dictionary comprehension. It takes the input dictionary and the list of keys to be removed as arguments. If the input dictionary is not a dictionary, it returns it as it is. If the value associated with a key is a dictionary, it calls the function recursively to remove keys from the nested dictionary. Finally, it returns a new dictionary with the specified keys removed and flattened. The output dictionary is printed.

  1. Define a function, say ‘remove_and_flatten()’, that takes two parameters – the dictionary to be processed and the list of keys to be removed.
  2. Define a base condition: if the input dictionary is not a dictionary, return the dictionary as it is.
  3. Define a dictionary comprehension that iterates over the items in the dictionary and filters out the keys to be removed. If the value associated with the key is a dictionary, recursively call the function to remove keys from the nested dictionary. Otherwise, assign the value to the key in the new dictionary.
  4. Return the new dictionary.
  5. Call the function with the input dictionary and keys to be removed.
  6. Print the output dictionary.

Example:

Python3




def remove_and_flatten(test_dict, rem_keys):
    if not isinstance(test_dict, dict):
        return test_dict
    return {key: remove_and_flatten(val, rem_keys) if isinstance(val, dict) else val
            for key, val in test_dict.items() if key not in rem_keys}
 
 
# initializing dictionary
test_dict = {'a': 14, 'b': 16, 'c': {'d': {'e': 7}}}
 
# printing original dictionary
print("The original dictionary is : " + str(test_dict))
 
# initializing removal keys
rem_keys = ["c", "d"]
 
# calling helper function for task
res = remove_and_flatten(test_dict, rem_keys)
 
# printing result
print("The removed and flattened dictionary : " + str(res))


Output

The original dictionary is : {'a': 14, 'b': 16, 'c': {'d': {'e': 7}}}
The removed and flattened dictionary : {'a': 14, 'b': 16}

Time complexity: The time complexity of this approach is O(N), where N is the number of keys in the input dictionary.

Auxiliary space: The auxiliary space required is O(N), where N is the number of keys in the input dictionary. This is because, at any point during the recursion, only the current level of the dictionary is being processed and the rest of the dictionary is being returned as it is.

Method 3: Using the json module

  1. Import the json module.
  2. Convert the dictionary to a JSON string using the json.dumps function.
  3. Load the JSON string back into a dictionary using the json.loads function.
  4. Use a list comprehension to filter out the keys to be removed from the dictionary.
  5. Return the filtered dictionary.

Python3




import json
 
def flatten_and_remove(test_dict, rem_keys):
    json_str = json.dumps(test_dict)
    flat_dict = json.loads(json_str)
 
    flat_dict = {key: val for key, val in flat_dict.items() if key not in rem_keys}
 
    return flat_dict
test_dict = {'a': 14, 'b': 16, 'c': {'d': {'e': 7}}}
rem_keys = ["c", "d"]
 
result = flatten_and_remove(test_dict, rem_keys)
 
print(result)


Output

{'a': 14, 'b': 16}

Time and Auxiliary Space Complexity: O(n) since it involves two passes over the dictionary – one to serialize it to JSON and one to deserialize it.

 The auxiliary space complexity is O(n) as well, since the serialized JSON string takes up additional memory.

Method 4: Using a stack and iteration

  1. Initialize an empty stack.
  2. Push the input dictionary onto the stack.
  3. Initialize an empty result dictionary.
  4. While the stack is not empty, pop the top dictionary from the stack.
  5. For each key-value pair in the dictionary, if the key is not in the removal keys list, then:
    a. If the value is a dictionary, push it onto the stack.
    b. If the value is not a dictionary, add the key-value pair to the result dictionary.
  6. Return the result dictionary.

Python3




def remove_and_flatten(test_dict, rem_keys):
    stack = [test_dict]
    result = {}
    while stack:
        curr_dict = stack.pop()
        for key, val in curr_dict.items():
            if key not in rem_keys:
                if isinstance(val, dict):
                    stack.append(val)
                else:
                    result[key] = val
    return result
test_dict = {'a': 14, 'b': 16, 'c': {'d': {'e': 7}}}
rem_keys = ["c", "d"]
res = remove_and_flatten(test_dict, rem_keys)
print(res)
# Output: {'a': 14, 'b': 16, 'e': 7}


Output

{'a': 14, 'b': 16}

Time complexity: O(N), where N is the total number of elements in the input dictionary.
Auxiliary space: O(M), where M is the maximum depth of nested dictionaries in the input dictionary.

Method 5: remove_and_flatten_dfs function:

  1. Define a function remove_and_flatten_dfs that takes two arguments: a dictionary test_dict and a list of keys to be removed rem_keys.
  2. Create an empty dictionary result_dict to store the flattened dictionary.
  3. Define a helper function dfs that takes two arguments: a dictionary curr_dict and a list of keys to be removed rem_keys.
  4. For each key-value pair in curr_dict, check if the key is in the list of keys to be removed (rem_keys). If it is, skip to the next key-value pair using the continue statement.
  5. If the value corresponding to the current key is a dictionary, call the dfs function recursively on this sub-dictionary with the same list of keys to be removed rem_keys.
  6. If the value corresponding to the current key is not a dictionary, add the current key-value pair to the result_dict.
  7. Call the dfs function with the input dictionary test_dict and the list of keys to be removed rem_keys.
  8. Return the flattened dictionary result_dict.
  9. Call the remove_and_flatten_dfs function with an example input dictionary test_dict and a list of keys to be removed rem_keys.
  10. Print the original dictionary and the flattened dictionary.

Python3




def remove_and_flatten_dfs(test_dict, rem_keys):
    result_dict = {}
 
    def dfs(curr_dict, rem_keys):
        for key, value in curr_dict.items():
            if key in rem_keys:
                continue
            if isinstance(value, dict):
                dfs(value, rem_keys)
            else:
                result_dict[key] = value
 
    dfs(test_dict, rem_keys)
    return result_dict
 
 
# example usage
test_dict = {'a': 14, 'b': 16, 'c': {'d': {'e': 7}}}
rem_keys = ["c", "d"]
 
# call the remove_and_flatten_dfs function and print the result
result_dict = remove_and_flatten_dfs(test_dict, rem_keys)
print("The original dictionary is:", test_dict)
print("The removed and flattened dictionary is:", result_dict)


Output

The original dictionary is: {'a': 14, 'b': 16, 'c': {'d': {'e': 7}}}
The removed and flattened dictionary is: {'a': 14, 'b': 16}

Time complexity: O(n), where n is the total number of key-value pairs in the dictionary.
Auxiliary space: O(n), where n is the total number of key-value pairs in the dictionary, because we need to store the result dictionary and call the dfs function recursively on sub-dictionaries.



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads