# Python – Extract selective keys’ values Including Nested Keys

Sometimes, while working with Python dictionaries, we can have a problem in which we need to extract selective keys’ values. This problem has been solved earlier, but sometimes, we can have multiple nestings and certain keys may be present in inner records. This problem caters all the nestings for extraction of keys’ values. Let’s discuss certain way in which this task can be solved.

Input
test_dict = {‘gfg’: {‘geeks’: {‘best’ : 3}}}
key_list = [‘best’, ‘geeks’]
Output : {‘geeks’: {‘best’: 3}, ‘best’: 3}

Input
test_dict = {‘gfg’: {‘geek’: {‘good’ : 3}}}
key_list = [‘best’, ‘geeks’]
Output : {}

Method 1: Using recursion + loop + yield
The combination of above functionalities can be used to solve this problem. In this, we perform the task of checking for key using conditional statements and check for nestings using recursion. The yield operator is used to dynamically return the key for assignment as it occurs.

## Python3

 `# Python3 code to demonstrate working of ` `# Extract selective keys' values [ Including Nested Keys ]` `# Using recursion + loop + yield`   `def` `get_vals(test_dict, key_list):` `   ``for` `i, j ``in` `test_dict.items():` `     ``if` `i ``in` `key_list:` `        ``yield` `(i, j)` `     ``yield` `from` `[] ``if` `not` `isinstance``(j, ``dict``) ``else` `get_vals(j, key_list)`   `# initializing dictionary` `test_dict ``=` `{``'gfg'``: {``'is'``: {``'best'` `: ``3``}}, ``'for'``: {``'all'` `: ``4``}, ``'geeks'``: ``5``}`   `# printing original dictionary` `print``("The original dictionary ``is` `: " ``+` `str``(test_dict))`   `# initializing keys list ` `key_list ``=` `[``'best'``, ``'geeks'``]`   `# Extract selective keys' values [ Including Nested Keys ]` `# Using recursion + loop + yield` `res ``=` `dict``(get_vals(test_dict, key_list))`   `# printing result ` `print``("The extracted values : " ``+` `str``(res)) `

Output :

```The original dictionary is : {'gfg': {'is': {'best': 3}}, 'for': {'all': 4}, 'geeks': 5}
The extracted values : {'best': 3, 'geeks': 5}```

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

Method 2-uses recursion and a helper function:

we define a helper function _get_vals_helper that recursively traverses the dictionary and extracts the values corresponding to the keys in key_list. The function returns a dictionary containing the extracted values. We call this function from the main get_vals function and return its result.

## Python3

 `def` `get_vals(test_dict, key_list):` `    ``def` `_get_vals_helper(sub_dict):` `        ``result ``=` `{}` `        ``for` `key, val ``in` `sub_dict.items():` `            ``if` `key ``in` `key_list:` `                ``result[key] ``=` `val` `            ``elif` `isinstance``(val, ``dict``):` `                ``nested_result ``=` `_get_vals_helper(val)` `                ``if` `nested_result:` `                    ``result[key] ``=` `nested_result` `        ``return` `result`   `    ``return` `_get_vals_helper(test_dict)`   `# initializing dictionary` `test_dict ``=` `{``'gfg'``: {``'is'``: {``'best'` `: ``3``}}, ``'for'``: {``'all'` `: ``4``}, ``'geeks'``: ``5``}`   `# printing original dictionary` `print``(``"The original dictionary is : "` `+` `str``(test_dict))`   `# initializing keys list ` `key_list ``=` `[``'best'``, ``'geeks'``]`   `# Extract selective keys' values [ Including Nested Keys ]` `# Using recursion and helper function` `res ``=` `get_vals(test_dict, key_list)`   `# printing result ` `print``(``"The extracted values : "` `+` `str``(res))`

Output

```The original dictionary is : {'gfg': {'is': {'best': 3}}, 'for': {'all': 4}, 'geeks': 5}
The extracted values : {'gfg': {'is': {'best': 3}}, 'geeks': 5}```

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

Method 3-Using recursion and a list comprehension.

• Initialize an empty list ‘result
• Loop through each item (key, value pair) in the ‘test_dict
• If the current key is in the ‘key_list‘, append the (key, value) pair to the ‘result’ list.
• If the current value is a dictionary, recursively call the ‘get_vals‘ function with the current value and ‘key_list’ and append the result to the ‘result‘ list.
• Convert the ‘result‘ list to a dictionary and return it.

## Python3

 `def` `get_vals(test_dict, key_list):` `    ``return` `[(k, v) ``for` `k, v ``in` `test_dict.items() ``if` `k ``in` `key_list] ``+` `\` `           ``[item ``for` `sub_dict ``in` `test_dict.values() ``if` `isinstance``(sub_dict, ``dict``)` `            ``for` `item ``in` `get_vals(sub_dict, key_list)]`   `test_dict ``=` `{``'gfg'``: {``'is'``: {``'best'` `: ``3``}}, ``'for'``: {``'all'` `: ``4``}, ``'geeks'``: ``5``}` `key_list ``=` `[``'best'``, ``'geeks'``]` `print``(``"The original dictionary is : "` `+` `str``(test_dict))`   `res ``=` `dict``(get_vals(test_dict, key_list))` `print``(``"The extracted values : "` `+` `str``(res))`

Output

```The original dictionary is : {'gfg': {'is': {'best': 3}}, 'for': {'all': 4}, 'geeks': 5}
The extracted values : {'geeks': 5, 'best': 3}```

Time Complexity: The time complexity of the function is O(n^2) where n is the number of elements in the input dictionary. This is because the function loops through each key-value pair in the dictionary and also recursively calls itself if a value is a dictionary. In the worst-case scenario, if all values are dictionaries, then the function will call itself n times for n elements in the dictionary, leading to a time complexity of O(n^2).

Auxiliary Space: The space complexity of the function is also O(n^2) in the worst-case scenario, where all values in the dictionary are dictionaries. This is because each recursive call creates a new list of (key, value) pairs to append to the ‘result’ list. Therefore, the space required for the ‘result’ list can grow up to O(n^2) with the increasing depth of recursion.

Method 4: Using a stack and iterative approach

Extracting values from a nested dictionary with given keys is by using a stack and an iterative approach.

Step-by-step approach:

• Create an empty dictionary result_dict to store the extracted values.
• Create an empty stack and push the given dictionary test_dict into it.
• While the stack is not empty:
a. Pop the top item from the stack.
b. If the popped item is a dictionary and contains any key from the key_list, extract the corresponding value and add it to result_dict.
c. If the popped item is a dictionary and contains any other dictionary, push those dictionaries onto the stack.
• Return the result_dict.

Below is the implementation of the above approach:

## Python3

 `def` `get_vals(test_dict, key_list):` `    ``result_dict ``=` `{}` `    ``stack ``=` `[test_dict]` `    `  `    ``while` `stack:` `        ``current_dict ``=` `stack.pop()` `        ``for` `k, v ``in` `current_dict.items():` `            ``if` `k ``in` `key_list:` `                ``result_dict[k] ``=` `v` `            ``elif` `isinstance``(v, ``dict``):` `                ``stack.append(v)` `    `  `    ``return` `result_dict` `test_dict ``=` `{``'gfg'``: {``'is'``: {``'best'` `: ``3``}}, ``'for'``: {``'all'` `: ``4``}, ``'geeks'``: ``5``}` `key_list ``=` `[``'best'``, ``'geeks'``]`   `res ``=` `get_vals(test_dict, key_list)` `print``(res)`

Output

`{'geeks': 5, 'best': 3}`

Time complexity: O(n), where n is the total number of items in the input dictionary.
Auxiliary space: O(m), where m is the maximum depth of the nested dictionaries in the input.

Method 5: Using a Queue and BFS (Breadth-First Search) Approach

• Create an empty queue.
• Enqueue the root node (test_dict) and an empty list to represent the path taken to reach it.
• While the queue is not empty:
• Dequeue a node and its path.
• If the node is a dictionary and not empty:
• For each key-value pair, add the key to the path and enqueue the value and the updated path.
• If the node is a leaf node and its key is in the key_list, yield the key-value pair.
• Return the result dictionary.

## Python3

 `from` `collections ``import` `deque`   `def` `get_vals_bfs(test_dict, key_list):` `    ``queue ``=` `deque([(test_dict, [])])` `    ``res ``=` `{}` `    `  `    ``while` `queue:` `        ``node, path ``=` `queue.popleft()` `        ``if` `isinstance``(node, ``dict``) ``and` `node:` `            ``for` `key, value ``in` `node.items():` `                ``queue.append((value, path ``+` `[key]))` `        ``elif` `path[``-``1``] ``in` `key_list:` `            ``res[path[``-``1``]] ``=` `node` `            `  `    ``return` `res` `# initializing dictionary` `test_dict ``=` `{``'gfg'``: {``'is'``: {``'best'` `: ``3``}}, ``'for'``: {``'all'` `: ``4``}, ``'geeks'``: ``5``}`   `# printing original dictionary` `print``(``"The original dictionary is : "` `+` `str``(test_dict))`   `# initializing keys list ` `key_list ``=` `[``'best'``, ``'geeks'``]`   `# Extract selective keys' values [ Including Nested Keys ]` `# Using BFS approach` `res ``=` `get_vals_bfs(test_dict, key_list)`   `# printing result ` `print``(``"The extracted values : "` `+` `str``(res)) `

Output

```The original dictionary is : {'gfg': {'is': {'best': 3}}, 'for': {'all': 4}, 'geeks': 5}
The extracted values : {'geeks': 5, 'best': 3}```

Time complexity: O(N), where N is the total number of elements in the dictionary.
Auxiliary space: O(N), where N is the maximum size of the queue.

Whether you're preparing for your first job interview or aiming to upskill in this ever-evolving tech landscape, GeeksforGeeks Courses are your key to success. We provide top-quality content at affordable prices, all geared towards accelerating your growth in a time-bound manner. Join the millions we've already empowered, and we're here to do the same for you. Don't miss out - check it out now!

Previous
Next