Python – Extract target key from other key values
Last Updated :
04 May, 2023
Sometimes, while working with Python dictionaries, we can have a problem in which we need to extract particular key on basis of other matching record keys when there is exact match. Lets discuss certain ways in which this task can be performed.
Method #1: Using loop + conditions This is one of the ways in which this task can be performed. In this, we iterate for the dictionary keys and check for each keys for matching values.
Python3
test_list = [{ 'name' : 'Manjeet' , 'English' : 14 , 'Maths' : 2 },
{ 'name' : 'Akshat' , 'English' : 7 , 'Maths' : 13 },
{ 'name' : 'Akash' , 'English' : 1 , 'Maths' : 17 },
{ 'name' : 'Nikhil' , 'English' : 10 , 'Maths' : 18 }]
print ("The original list is : " + str (test_list))
filt_key = { 'English' : 7 , 'Maths' : 13 }
res = []
for sub in test_list:
if sub["English"] = = filt_key["English"] and sub["Maths"] = = filt_key["Maths"]:
res.append(sub[ 'name' ])
print ("The filtered result : " + str (res))
|
Output :
The original list is : [{‘name’: ‘Manjeet’, ‘English’: 14, ‘Maths’: 2}, {‘name’: ‘Akshat’, ‘English’: 7, ‘Maths’: 13}, {‘name’: ‘Akash’, ‘English’: 1, ‘Maths’: 17}, {‘name’: ‘Nikhil’, ‘English’: 10, ‘Maths’: 18}] The filtered result : [‘Akshat’]
Time Complexity: O(n)
Auxiliary Space: O(n)
Method #2: Using loop + conditions ( for multiple/unknown keys ) This performs the task in similar way in which above method does. The advantage of using this method is that one doesn’t need to feed all keys manually in conditions.
Python3
def hlper_func(test_keys, filt_key):
for key in test_keys.keys():
if key in filt_key:
if test_keys[key] ! = int (filt_key[key]):
return False
return True
test_list = [{ 'name' : 'Manjeet' , 'English' : 14 , 'Maths' : 2 },
{ 'name' : 'Akshat' , 'English' : 7 , 'Maths' : 13 },
{ 'name' : 'Akash' , 'English' : 1 , 'Maths' : 17 },
{ 'name' : 'Nikhil' , 'English' : 10 , 'Maths' : 18 }]
print ("The original list is : " + str (test_list))
filt_key = { 'English' : 7 , 'Maths' : 13 }
res = []
for sub in test_list:
if hlper_func(sub, filt_key):
res.append(sub[ 'name' ])
print ("The filtered result : " + str (res))
|
Output :
The original list is : [{‘name’: ‘Manjeet’, ‘English’: 14, ‘Maths’: 2}, {‘name’: ‘Akshat’, ‘English’: 7, ‘Maths’: 13}, {‘name’: ‘Akash’, ‘English’: 1, ‘Maths’: 17}, {‘name’: ‘Nikhil’, ‘English’: 10, ‘Maths’: 18}] The filtered result : [‘Akshat’]
Time complexity: O(n*m), where n is the length of the input list and m is the length of the filter dictionary keys.
Auxiliary space: O(1), as we are not creating any additional data structures to store the intermediate results. We are simply iterating over the input list and filter dictionary and storing the required output in a list.
Method #3: Using Recursive method.
Python3
def extract_target_key(test_list, filt_key, res = []):
if not test_list:
return res
if test_list[ 0 ][ "English" ] = = filt_key[ "English" ] and test_list[ 0 ][ "Maths" ] = = filt_key[ "Maths" ]:
res.append(test_list[ 0 ][ 'name' ])
return extract_target_key(test_list[ 1 :], filt_key, res)
test_list = [{ 'name' : 'Manjeet' , 'English' : 14 , 'Maths' : 2 },
{ 'name' : 'Akshat' , 'English' : 7 , 'Maths' : 13 },
{ 'name' : 'Akash' , 'English' : 1 , 'Maths' : 17 },
{ 'name' : 'Nikhil' , 'English' : 10 , 'Maths' : 18 }]
filt_key = { 'English' : 7 , 'Maths' : 13 }
print ( "The original list is : " + str (test_list))
res = extract_target_key(test_list, filt_key)
print ( "The filtered result : " + str (res))
|
Output
The original list is : [{'name': 'Manjeet', 'English': 14, 'Maths': 2}, {'name': 'Akshat', 'English': 7, 'Maths': 13}, {'name': 'Akash', 'English': 1, 'Maths': 17}, {'name': 'Nikhil', 'English': 10, 'Maths': 18}]
The filtered result : ['Akshat']
Time Complexity: O(n)
Auxiliary Space: O(n)
Method #4: Using List Comprehension
Step-by-step Algorithm:
- Initialize a list of dictionaries called test_list with some values.
- Initialize a dictionary called filt_key with filter values.
- Use list comprehension to extract the names from the dictionaries in test_list that satisfy the filter condition.
- Print the filtered result.
Python3
test_list = [{ 'name' : 'Manjeet' , 'English' : 14 , 'Maths' : 2 },
{ 'name' : 'Akshat' , 'English' : 7 , 'Maths' : 13 },
{ 'name' : 'Akash' , 'English' : 1 , 'Maths' : 17 },
{ 'name' : 'Nikhil' , 'English' : 10 , 'Maths' : 18 }]
filt_key = { 'English' : 7 , 'Maths' : 13 }
res = [d[ 'name' ] for d in test_list if d[ 'English' ] = = filt_key[ 'English' ] and d[ 'Maths' ] = = filt_key[ 'Maths' ]]
print ( "The filtered result: " + str (res))
|
Output
The filtered result: ['Akshat']
Time Complexity: The list comprehension iterates over each dictionary in the test_list. Therefore, the time complexity of this algorithm is O(N), where N is the length of the test_list.
Auxiliary Space: The algorithm initializes a list called res. Therefore, the auxiliary space complexity is O(N), where N is the length of the test_list.
Method #5: Using map and lambda functions to extract values from matching key elements:
Algorithm:
- Define a list of dictionaries test_list and a dictionary to filter with filt_key.
- Use the filter() function with a lambda function to create a new list of dictionaries that match the filt_key.
- Use the map() function with a lambda function to extract the “name” value from each dictionary in the filtered list.
- Convert the resulting map object to a list
- Print the filtered list of names.
Python3
test_list = [{ 'name' : 'Manjeet' , 'English' : 14 , 'Maths' : 2 },
{ 'name' : 'Akshat' , 'English' : 7 , 'Maths' : 13 },
{ 'name' : 'Akash' , 'English' : 1 , 'Maths' : 17 },
{ 'name' : 'Nikhil' , 'English' : 10 , 'Maths' : 18 }]
filt_key = { 'English' : 7 , 'Maths' : 13 }
res = list ( map ( lambda x: x[ 'name' ], filter ( lambda x: x[ "English" ] = = filt_key[ "English" ] and x[ "Maths" ] = = filt_key[ "Maths" ], test_list)))
print ( "The filtered result : " + str (res))
|
Output
The filtered result : ['Akshat']
Time complexity: O(n), where n is the number of elements in test_list. The filter() function and the map() function both iterate over the list once.
Auxiliary Space: O(k), where k is the number of matching dictionaries in test_list. The filter() function returns a new list containing only the matching dictionaries, and the map() function returns a map object containing only the “name” values from the matching dictionaries. The resulting list res contains only the names, so its size is equal to the number of matching dictionaries.
Method #6: Using filter and lambda functions:
- Initialize filter items.
- Define a lambda function that checks if a dictionary has matching values for the filter items.
- Use the filter() function along with the lambda function to extract the dictionaries that match the filter items.
- Use a list comprehension to extract the target key from the matching dictionaries.
- Return the resulting list.
Python3
test_list = [{ 'name' : 'Manjeet' , 'English' : 14 , 'Maths' : 2 },
{ 'name' : 'Akshat' , 'English' : 7 , 'Maths' : 13 },
{ 'name' : 'Akash' , 'English' : 1 , 'Maths' : 17 },
{ 'name' : 'Nikhil' , 'English' : 10 , 'Maths' : 18 }]
print ( "The original list is : " + str (test_list))
filt_key = { 'English' : 7 , 'Maths' : 13 }
filtered_dicts = filter ( lambda x: all (x[key] = = filt_key[key] for key in filt_key), test_list)
res = [d[ 'name' ] for d in filtered_dicts]
print ( "The filtered result : " + str (res))
|
Output
The original list is : [{'name': 'Manjeet', 'English': 14, 'Maths': 2}, {'name': 'Akshat', 'English': 7, 'Maths': 13}, {'name': 'Akash', 'English': 1, 'Maths': 17}, {'name': 'Nikhil', 'English': 10, 'Maths': 18}]
The filtered result : ['Akshat']
Time complexity: O(n), where n is the number of dictionaries in the input list.
Auxiliary space: O(n), where n is the number of dictionaries in the input list.
Method #7 : using the reduce function from the functools module.
Steps-by-step appraoch:
- Import the functools module.
- Initialize the list of keys that need to be checked for equality with the specified values.
- Use the reduce function to filter out the dictionaries that don’t have the specified key-value pairs.
- Use another lambda function to extract the value of the target key from each dictionary that meets the condition in step 3.
- Filter out the None values from the result of the reduce function.
- Return the list of values of the target key.
Python3
import functools
test_list = [{ 'name' : 'Manjeet' , 'English' : 14 , 'Maths' : 2 },
{ 'name' : 'Akshat' , 'English' : 7 , 'Maths' : 13 },
{ 'name' : 'Akash' , 'English' : 1 , 'Maths' : 17 },
{ 'name' : 'Nikhil' , 'English' : 10 , 'Maths' : 18 }]
filt_key = { 'English' : 7 , 'Maths' : 13 }
res = functools. reduce ( lambda acc, d: acc + [d.get( 'name' )] if all (d.get(key) = = value for key, value in filt_key.items()) and d.get( 'name' ) else acc, test_list, [])
print ( "The filtered result : " + str (res))
|
Output
The filtered result : ['Akshat']
The time complexity of this method is also O(n), where n is the number of dictionaries in the list.
The auxiliary space is O(1) since we are using a constant amount of memory for variables.
Method #8 : Using heapq :
Algorithm:
- Define and initialize a list of dictionaries test_list containing student information.
- Define and initialize a dictionary filt_key containing filter criteria.
- Define an empty list res to store the filtered results.
- Use a loop to iterate over each dictionary in test_list.
- For each dictionary, check if its English and Maths keys match the corresponding values in filt_key. If the
- match is found, add the value of the name key to the res list.
- Use the heapq module to convert the res list into a min heap, sorting the names in lexicographic order.
- Convert the min heap back to a list and assign the result to the res variable.
- Print the filtered result.
Python3
import heapq
test_list = [
{ 'name' : 'Manjeet' , 'English' : 14 , 'Maths' : 2 },
{ 'name' : 'Akshat' , 'English' : 7 , 'Maths' : 13 },
{ 'name' : 'Akash' , 'English' : 1 , 'Maths' : 17 },
{ 'name' : 'Nikhil' , 'English' : 10 , 'Maths' : 18 }
]
filt_key = { 'English' : 7 , 'Maths' : 13 }
res = []
for d in test_list:
if d[ 'English' ] = = filt_key[ 'English' ] and d[ 'Maths' ] = = filt_key[ 'Maths' ]:
heapq.heappush(res, d[ 'name' ])
res = list (res)
print ( "The filtered result : " + str (res))
|
Output
The filtered result : ['Akshat']
Time Complexity:
The time complexity of the given code is O(N log N), where N is the number of dictionaries in the test_list. This is because the code iterates over each dictionary in the test_list once, which takes O(N) time. Then, it uses the heapq.heappush() method to add the names to the res list, which takes O(log N) time for each insertion. Since the heappush() method is called N times, the total time complexity becomes O(N log N). Finally, the conversion of the heap back to a list takes O(N log N) time.
Space Complexity:
The space complexity of the given code is O(N), where N is the number of dictionaries in the test_list. This is because the code creates a list res to store the filtered results, which can have up to N elements. Additionally, the heapq module uses extra space to create the min heap, which can also have up to N elements. Therefore, the total space complexity becomes O(N).
Share your thoughts in the comments
Please Login to comment...