Open In App

Python – Conditional Join Dictionary List

Last Updated : 03 May, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

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_list2 = [{“good” : 4, “best”: 2}, {“geeks” : 2, “best” : 3 },  {“CS” : 2, “best” : 10 } ], test_key = “best”
Output : [{‘gfg’: 1, ‘is’: 3, ‘best’: 2, ‘good’: 4}, {‘gfg’: 1, ‘best’: 6}, {‘all’: 7, ‘best’: 10, ‘CS’: 2}]
Explanation : best has 2 in both dictionaries of 0th index, hence at index 0, dictionaries are merged.

Input : test_list1 = [{“gfg” : 1, “is” : 3, “best”: 3}, {“gfg” : 1, “best” : 6}, {“all” : 7, “best” : 10} ],
test_list2 = [{“good” : 4, “best”: 2}, {“geeks” : 2, “best” : 3 },  {“CS” : 2, “best” : 10 } ], test_key = “best”
Output : [{‘gfg’: 1, ‘is’: 3, ‘best’: 3}, {‘gfg’: 1, ‘best’: 6}, {‘all’: 7, ‘best’: 10, ‘CS’: 2}]
Explanation : best has 10 in both dictionaries of 2nd index, hence at index 2, dictionaries are merged.

Method 1: Using next() + update()

In this, we use generator expression to check if dictionary’s key matches the similar index dictionary key, if yes, then all the corresponding keys are merged using update().

Python3




# Python3 code to demonstrate working of
# Conditional Join Dictionary List
# Using update() + next()
 
# initializing lists
test_list1 = [{"gfg": 1, "is": 3, "best": 2}, {
    "gfg": 1, "best": 6}, {"all": 7, "best": 10}]
test_list2 = [{"good": 4, "best": 2}, {
    "geeks": 2, "best": 3},  {"CS": 2, "best": 10}]
 
# printing original list
print("The original list 1 is : " + str(test_list1))
print("The original list 2 is : " + str(test_list2))
 
# initializing test key
test_key = "best"
 
for sub1 in test_list1:
 
    # checking for matching key
    temp = next(
        (itm for itm in test_list2 if sub1[test_key] == itm[test_key]), None)
    if(temp):
 
        # performing update
        sub1.update(temp)
 
# printing result
print("Joined result : " + str(test_list1))


Output

The original list 1 is : [{'gfg': 1, 'is': 3, 'best': 2}, {'gfg': 1, 'best': 6}, {'all': 7, 'best': 10}]
The original list 2 is : [{'good': 4, 'best': 2}, {'geeks': 2, 'best': 3}, {'CS': 2, 'best': 10}]
Joined result : [{'gfg': 1, 'is': 3, 'best': 2, 'good': 4}, {'gfg': 1, 'best': 6}, {'all': 7, 'best': 10, 'CS': 2}]

Time Complexity: O(n*m), where n is the length of test_list1 and m is the length of test_list2. 

Auxiliary Space: O(1)

Method #2: Using nested loops

Use nested loops to iterate over each dictionary in the first list, and for each dictionary, it checks if the given key is present in it. If the key is present, it iterates over each dictionary in the second list and checks if the key is present in it and if the value of the key in the first dictionary matches with the value of the key in the second dictionary. If this condition is met, the two dictionaries are merged and added to the output list. If the key is not present in the second dictionary, only the first dictionary is added to the output list.

Step-by-step approach:

1. Traverse through each dictionary in the first list.
2. Check if the key is present in the dictionary.
3. If the key is present, find the corresponding dictionary in the second list.
4. If the key is present in the second dictionary as well, merge the two dictionaries and add it to the output list.
5. Return the output list.

Python3




def conditional_join_dict_list(test_list1, test_list2, test_key):
    output = []
    for dict1 in test_list1:
        if test_key in dict1:
            for dict2 in test_list2:
                if test_key in dict2 and dict1[test_key] == dict2[test_key]:
                    output.append({**dict1, **dict2})
                    break
            else:
                output.append(dict1)
    return output
test_list1 = [{"gfg": 1, "is": 3, "best": 2}, {
    "gfg": 1, "best": 6}, {"all": 7, "best": 10}]
test_list2 = [{"good": 4, "best": 2}, {
    "geeks": 2, "best": 3},  {"CS": 2, "best": 10}]
test_key = "best"
print(conditional_join_dict_list(test_list1, test_list2, test_key))


Output

[{'gfg': 1, 'is': 3, 'best': 2, 'good': 4}, {'gfg': 1, 'best': 6}, {'all': 7, 'best': 10, 'CS': 2}]

Time Complexity: O(n^2), where n is the length of the input lists.
Auxiliary Space: O(n), as the output list can have at most n dictionaries.

Method 3:Using list comprehension and dictionary comprehension

The approach used in the conditional_join_dicts function is a list comprehension that iterates over each dictionary in dicts_list_1 and dicts_list_2. For each dictionary in dicts_list_1, it checks if the value of the common_key exists in any of the dictionaries in dicts_list_2. If there is a match, the two dictionaries are combined using the ** operator, which merges them into a new dictionary. The resulting dictionary is added to a new list of joined dictionaries. Finally, the function returns the list of joined dictionaries.

Step-by-step approach:

1. Define a function that takes in two lists of dictionaries and a common key as input.
2. Create an empty list called joined_dicts to hold the merged dictionaries.
3. Iterate through each dictionary in the first list using a for loop.
4. Within the for loop, iterate through each dictionary in the second list using another for loop.
5. If the value of the common key in the current dictionary from the first list matches the value of the common key in the current dictionary from the second list, use the spread operator to merge the two dictionaries, and append the resulting dictionary to the joined_dicts list.
6. Return the joined_dicts list of merged dictionaries.

Python3




def conditional_join_dicts(dicts_list_1, dicts_list_2, common_key):
    joined_dicts = [{**dict_1, **dict_2, common_key: dict_1[common_key]} for dict_1 in dicts_list_1 for dict_2 in dicts_list_2 if dict_1.get(common_key) == dict_2.get(common_key)]
    for dict_1 in dicts_list_1:
        if dict_1.get(common_key) not in [dict_2.get(common_key) for dict_2 in dicts_list_2]:
            joined_dicts.append(dict_1)
    return joined_dicts
 
# Test the function
dicts_list_1 = [{'gfg': 1, 'is': 3, 'best': 2}, {'gfg': 1, 'best': 6}, {'all': 7, 'best': 10}]
dicts_list_2 = [{'good': 4, 'best': 2}, {'geeks': 2, 'best': 3}, {'CS': 2, 'best': 10}]
common_key = 'best'
 
output = conditional_join_dicts(dicts_list_1, dicts_list_2, common_key)
desired_output = [{'gfg': 1, 'is': 3, 'best': 2, 'good': 4}, {'gfg': 1, 'best': 6}, {'all': 7, 'best': 10, 'CS': 2}]
print("Input: dicts_list_1 =", dicts_list_1, "dicts_list_2 =", dicts_list_2, "common_key =", common_key)
print("Output:", output)


Output

Input: dicts_list_1 = [{'gfg': 1, 'is': 3, 'best': 2}, {'gfg': 1, 'best': 6}, {'all': 7, 'best': 10}] dicts_list_2 = [{'good': 4, 'best': 2}, {'geeks': 2, 'best': 3}, {'CS': 2, 'best': 10}] common_key = best
Output: [{'gfg': 1, 'is': 3, 'best': 2, 'good': 4}, {'all': 7, 'best': 10, 'CS': 2}, {'gfg': 1, 'best': 6}]

The time complexity of the conditional_join_dicts function is O(n^2), where n is the total number of key-value pairs in both input lists, as there are two nested loops that iterate through all the pairs in both lists. The time complexity of the dictionary concatenation operation is O(m), where m is the number of key-value pairs in the resulting dictionary.

The space complexity of the function is O(k), where k is the total number of key-value pairs in the output list, as it creates a new dictionary for each pair in the output list. In addition, the function also creates temporary dictionaries for each pair in both input lists during the concatenation process. Therefore, the total space complexity of the function can be considered as O(k + n), where k << n.

Method 4: Using the set intersection of common keys of each dictionary in both lists. 

Step-by-step approach:

  • Create a set of common keys in dicts_list_1 and dicts_list_2 using set intersection operation.
  • Create an empty list to hold the joined dictionaries.
    Iterate over each dictionary in dicts_list_1.
  • If the common key is present in the current dictionary, find the matching dictionary in dicts_list_2 using the common key and merge both dictionaries using dictionary unpacking.
  • Append the merged dictionary to the joined_dicts list.
  • Return the joined_dicts list.

Python3




def conditional_join_dicts(dicts_list_1, dicts_list_2, common_key):
    # Step 1
    common_keys = set(dicts_list_1[0]).intersection(set(dicts_list_2[0]))
    for i in range(1, len(dicts_list_1)):
        common_keys = common_keys.intersection(set(dicts_list_1[i]))
    for i in range(1, len(dicts_list_2)):
        common_keys = common_keys.intersection(set(dicts_list_2[i]))
 
    # Step 2
    joined_dicts = []
 
    # Step 3-6
    for dict_1 in dicts_list_1:
        if common_key in dict_1:
            matching_dicts = [dict_2 for dict_2 in dicts_list_2 if dict_2.get(common_key) == dict_1.get(common_key)]
            for dict_2 in matching_dicts:
                merged_dict = {**dict_1, **dict_2}
                joined_dicts.append(merged_dict)
    return joined_dicts
 
# Test the function
dicts_list_1 = [{'gfg': 1, 'is': 3, 'best': 2}, {'gfg': 1, 'best': 6}, {'all': 7, 'best': 10}]
dicts_list_2 = [{'good': 4, 'best': 2}, {'geeks': 2, 'best': 3}, {'CS': 2, 'best': 10}]
common_key = 'best'
 
output = conditional_join_dicts(dicts_list_1, dicts_list_2, common_key)
desired_output = [{'gfg': 1, 'is': 3, 'best': 2, 'good': 4}, {'gfg': 1, 'best': 6}, {'all': 7, 'best': 10, 'CS': 2}]
print("Input: dicts_list_1 =", dicts_list_1, "dicts_list_2 =", dicts_list_2, "common_key =", common_key)
print("Output:", output)
 
# Time complexity: O(n*m*k) where n and m are the lengths of dicts_list_1 and dicts_list_2 respectively and k is the number of common keys between them.
# Auxiliary space: O(n*m) to store the joined_dicts list.


Output

Input: dicts_list_1 = [{'gfg': 1, 'is': 3, 'best': 2}, {'gfg': 1, 'best': 6}, {'all': 7, 'best': 10}] dicts_list_2 = [{'good': 4, 'best': 2}, {'geeks': 2, 'best': 3}, {'CS': 2, 'best': 10}] common_key = best
Output: [{'gfg': 1, 'is': 3, 'best': 2, 'good': 4}, {'all': 7, 'best': 10, 'CS': 2}]

Time complexity: O(n*m*k) where n and m are the lengths of dicts_list_1 and dicts_list_2 respectively and k is the number of common keys between them.
Auxiliary space: O(n*m) to store the joined_dicts list.



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads