Open In App

Python – Merge keys by values

Improve
Improve
Like Article
Like
Save
Share
Report

Given a dictionary, merge the keys to map to common values.

Examples:

Input : test_dict = {1:6, 8:1, 9:3, 10:3, 12:6, 4:9, 2:3} 
Output : {'1-12': 6, '2-9-10': 3, '4': 9, '8': 1} 
Explanation : All the similar valued keys merged.
Input : test_dict = {1:6, 8:1, 9:3, 4:9, 2:3} 
Output : {'1': 6, '2-9': 3, '4': 9, '8': 1} 
Explanation : All the similar valued keys merged. 

Method 1: Using defaultdict() + loop

This task is performed in 2 steps, first, group all the values and storing keys, and in 2nd step, map merged keys to common values.

Python3




# Python3 code to demonstrate working of
# Merge keys by values
# Using defaultdict() + loop
from collections import defaultdict
 
# initializing dictionary
test_dict = {1: 6, 8: 1, 9: 3, 10: 3, 12: 6, 4: 9, 2: 3}
 
# printing original dictionary
print("The original dictionary is : " + str(test_dict))
 
# grouping values
temp = defaultdict(list)
for key, val in sorted(test_dict.items()):
    temp[val].append(key)
 
res = dict()
# merge keys
for key in temp:
    res['-'.join([str(ele) for ele in temp[key]])] = key
 
# printing result
print("The required result : " + str(res))


Output:

The original dictionary is : {1: 6, 8: 1, 9: 3, 10: 3, 12: 6, 4: 9, 2: 3} 
The required result : {‘1-12’: 6, ‘2-9-10’: 3, ‘4’: 9, ‘8’: 1}

Time Complexity: O(n), where n is the length of the list test_dict 
Auxiliary Space: O(n) additional space of size n is created where n is the number of elements in the res list

Method 2: Using a dictionary to store the merged keys

Approach:

  1. Create an empty dictionary merged_dict to store the merged keys and values.
  2. Loop through each key-value pair in the input dictionary test_dict.
  3. Check if the value already exists in the merged_dict.
  4. If the value does not exist, create a new key-value pair in the merged_dict with the value as the key and a list containing the key as the value.
  5. If the value already exists, append the key to the list of keys corresponding to that value in the merged_dict.
  6. Loop through each key in the merged_dict.
  7. If the length of the list of keys corresponding to that value is 1, replace the list with a single key.
  8. If the length of the list of keys corresponding to that value is greater than 1, sort the list of keys in ascending order, join them with a dash (‘-‘), and replace the list with the joined string.
  9. Return the merged dictionary and print the elements in the dictionary. 

Python3




def merge_keys(test_dict):
 
    merged_dict = {}
 
    for key, value in test_dict.items():
        if value not in merged_dict:
            merged_dict[value] = [key]
        else:
            merged_dict[value].append(key)
 
    for key in merged_dict:
        if len(merged_dict[key]) == 1:
            merged_dict[key] = merged_dict[key][0]
        else:
            merged_dict[key] = '-'.join([str(k)
                                          
                                        for k in sorted(merged_dict[key])])
    return merged_dict
 
 
test_dict1 = {1: 6, 8: 1, 9: 3, 10: 3, 12: 6, 4: 9, 2: 3}
merged_dict1 = merge_keys(test_dict1)
print(merged_dict1)
 
test_dict2 = {1: 6, 8: 1, 9: 3, 4: 9, 2: 3}
merged_dict2 = merge_keys(test_dict2)
print(merged_dict2)


Output

{6: '1-12', 1: 8, 3: '2-9-10', 9: 4}
{6: 1, 1: 8, 3: '2-9', 9: 4}

Time complexity: O(N log(N)) due to sorting the merged keys
Auxiliary Space: O(N)

Method – Using itertools.groupby()

Steps:

  1. Initialize an empty dictionary res.
  2. Use itertools.groupby() to group the original dictionary’s items by their values, and sort them based on the values.
  3. Loop over the groups, and for each group, get the keys and values and merge the keys using ‘-‘.join() if there is more than one key, otherwise just use the single key.
  4. Assign the merged key and value to the res dictionary and print the res dictionary.

Below is the implementation of the above approach:

Python3




import itertools
from functools import reduce
 
# Initializing dictionary
test_dict = {1: 6, 8: 1, 9: 3, 10: 3, 12: 6, 4: 9, 2: 3}
 
# printing original dictionary
print("The original dictionary is : " + str(test_dict))
 
# using itertools.groupby() to group by values
# and then reduce to merge keys
res = {}
 
for val, grp in itertools.groupby(sorted(test_dict.items(), key=lambda x: x[1]), lambda x: x[1]):
    keys = [str(i[0]) for i in list(grp)]
    if len(keys) == 1:
        res[keys[0]] = val
    else:
        res['-'.join(keys)] = val
 
# Printing result
print("The required result : " + str(res))
 
# This code is contributed by Jyothi pinjala


Output

The original dictionary is : {1: 6, 8: 1, 9: 3, 10: 3, 12: 6, 4: 9, 2: 3}
The required result : {'8': 1, '9-10-2': 3, '1-12': 6, '4': 9}

Time Complexity: O(n log n) (sorting the dictionary items)
Space Complexity: O(n) (creating the res dictionary and the keys list for each group)

Method – Using list comprehension

Steps:

  1. Create an empty dictionary res to store the result
  2. Using a set, extract all unique values from the given dictionary
  3. Using a dictionary comprehension, group the keys of the given dictionary according to their values in a dictionary temp
  4. Iterate over each key in temp and concatenate its values separated by ‘-‘ to create a new key in res, with the corresponding value being the original key value from temp
  5. Return res as the required result.

Python3




# Python3 code to demonstrate working of
# Merge keys by values
# using list comprehension
 
# Initializing dictionary
test_dict = {1: 6, 8: 1, 9: 3, 10: 3, 12: 6, 4: 9, 2: 3}
 
# Printing original dictionary
print("The original dictionary is : " + str(test_dict))
 
#  Grouping values using dictionary comprehension
temp = {val: [key for key, value in test_dict.items() if value == val]
        for val in set(test_dict.values())}
  
# Empty dictionary
res = {}
 
# Merge keys
for key in temp:
    res['-'.join([str(ele) for ele in temp[key]])] = key
 
# Printing result
print("The required result : " + str(res))
 
# This code is contrinuted by Pushpa


Output

The original dictionary is : {1: 6, 8: 1, 9: 3, 10: 3, 12: 6, 4: 9, 2: 3}
The required result : {'8': 1, '9-10-2': 3, '1-12': 6, '4': 9}

Time Complexity: O(n^2), where n is the length of the input dictionary. This is because the dictionary comprehension used to group the keys by values iterates over the entire input dictionary for each unique value, resulting in n^2 operations.

Auxiliary Space: O(n), where n is the length of the input dictionary. This is because we create a dictionary temp to store the keys grouped by values, which can have a maximum of n key-value pairs. The dictionary res and the set of unique values also contribute to the space complexity, but they have a maximum size of n as well. Therefore, the overall space complexity is O(n).

Method 4: Using nested for loop

Approach:

  1. Initialize an empty dictionary merged_dict.
  2. Loop through each key-value pair in the original dictionary test_dict.
  3. Check if the value of the current key is already in the merged_dict as a key.
  4. If the value is not in merged_dict, add a new key-value pair with the value as key and a list containing the key as the value.
  5. If the value is already in merged_dict, append the key to the existing list of keys for that value.
  6. Convert the list of keys for each value into a string with ‘-‘ as the separator.
  7. Add the new key-value pair to the res dictionary with the string of merged keys as the key and the value as the value.
  8. Print the resultant list. 

Python3




# Python3 code to demonstrate working of
# Merge keys by values
# Using nested loop
 
# Initializing dictionary
test_dict = {1: 6, 8: 1, 9: 3, 10: 3, 12: 6, 4: 9, 2: 3}
 
# Printing original dictionary
print("The original dictionary is : " + str(test_dict))
 
merged_dict = {}
res = {}
 
# Loop through each key-value pair in the dictionary
for key, value in test_dict.items():
 
    # Checking if value is already in the merged_dict
    if value in merged_dict:
        merged_dict[value].append(key)
    else:
        merged_dict[value] = [key]
 
# Looping through each value in the merged_dict
for value in merged_dict:
 
    # Creating string of merged keys separated by '-'
    key_str = '-'.join([str(key) for key in merged_dict[value]])
 
    # Adding new key-value pair to the result dictionary
    res[key_str] = value
 
# Printing result
print("The required result : " + str(res))


Output

The original dictionary is : {1: 6, 8: 1, 9: 3, 10: 3, 12: 6, 4: 9, 2: 3}
The required result : {'1-12': 6, '8': 1, '9-10-2': 3, '4': 9}

Time complexity: O(n), where n is the number of key-value pairs in the dictionary.
Auxiliary space: O(n), to store the merged_dict and res dictionaries.



Last Updated : 18 May, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads