Open In App

Python – Convert List to key-value list by prefix grouping

Given a list, convert it to consecutive key-value lists, grouping by a prefix.

Input : test_list = ["GFG-1", 4, 6, "GFG-2", 3, "GFG-3", 9, 2], temp = "GF" 
Output : {'GFG-1': [4, 6], 'GFG-2': [3], 'GFG-3': [9, 2]} 
Explanation : All grouped till next prefix. 
Input : test_list = ["MRK-1", 4, 6, "MRK-2", 3, "MRK-3", 9, 2], temp = "MR" 
Output : {'MRK-1': [4, 6], 'MRK-2': [3], 'MRK-3': [9, 2]}
Explanation : All grouped till next prefix, "MR".

Method 1: Using groupby() + startswith() + lambda



The combination of the above functions can be used to solve this problem. In this, we employ grouping of all elements by prefix using groupby() and lambda functions to assist in performing segregation of prefix for grouping.

Step-by-step approach:



Below is the implementation of the above approach:




# Python3 code to demonstrate working of
# Convert List to key-value list by prefix grouping
# Using groupby() + startswith() + lambda
 
from itertools import groupby
 
# initializing list
test_list = ["GFG-1", 4, 6, 7, 10, "GFG-2", 2, 3, "GFG-3", 9, 2, 4, 6]
 
# printing original list
print("The original list : " + str(test_list))
 
# initializing prefix
temp = "GFG"
 
res = {}
# Extracting result from grouped by prefix
for key, val in groupby(test_list, lambda ele: str(ele).startswith(temp)):
 
    # checking for existing key
    if key:
        k = next(val)
    else:
        res[k] = list(val)
 
# Printing result
print("The constructed dictionary : " + str(res))

Output
The original list : ['GFG-1', 4, 6, 7, 10, 'GFG-2', 2, 3, 'GFG-3', 9, 2, 4, 6]
The constructed dictionary : {'GFG-1': [4, 6, 7, 10], 'GFG-2': [2, 3], 'GFG-3': [9, 2, 4, 6]}

Time Complexity: O(n), where n is the elements of dictionary
Auxiliary Space: O(n), where n is the size of a dictionary

Method 2: Using defaultdict

Creates a defaultdict with the list as the default value type. Then, it iterates through the test_list and uses the string method startswith() to check if the element starts with the given prefix. If it does, it sets the key to the element. If not, it appends the element to the list associated with the current key in the defaultdict. Finally, it prints the resulting dictionary.




from collections import defaultdict
 
# initializing list
test_list = ["GFG-1", 4, 6, 7, 10, "GFG-2", 2, 3, "GFG-3", 9, 2, 4, 6]
 
# initializing prefix
temp = "GFG"
 
res = defaultdict(list)
 
# iterating through the list and appending the values to the dictionary
for i in test_list:
    if str(i).startswith(temp):
        key = i
    else:
        res[key].append(i)
 
# printing result
print("The constructed dictionary : " + str(res))

Output
The constructed dictionary : defaultdict(<class 'list'>, {'GFG-1': [4, 6, 7, 10], 'GFG-2': [2, 3], 'GFG-3': [9, 2, 4, 6]})

Time complexity: O(n), where n is the length of the input list test_list.
Auxiliary space: O(n), because the resulting dictionary can have up to n/2 keys (in the worst case, when all elements in the list start with the prefix), and each key can have at most n/2 values (in the worst case when there are no elements starting with the prefix). 

Method 3: Using dictionary comprehension method to construct the dictionary

It iterates through the elements of the list using a ‘for’ loop and checks whether an element starts with the prefix string ‘temp’. If an element in the list starts with the prefix string ‘temp’, it initializes a new empty list as the value for the dictionary key corresponding to that element. If an element in the list does not start with the prefix string ‘temp’, it appends that element to the value list corresponding to the current dictionary key.

Since the program uses a ‘for’ loop to iterate through the elements of the list, it is not using the dictionary comprehension method. Rather, it is using a standard for loop to construct the dictionary.

Approach:

  1. Initialize a list called ‘test_list‘ with multiple values of different data types.
  2. Initialize a variable called ‘temp’ with a string “GFG” to search for the elements starting with this string.
  3. Initialize an empty dictionary called ‘res‘ to store the elements from the list.
  4. Iterate through the list using a ‘for‘ loop to check whether an element starts with the prefix string 
  5. If an element in the list starts with the prefix string ‘temp‘, initialize a new empty list as the value for the dictionary key corresponding to that element.
  6. If an element in the list does not start with the prefix string ‘temp‘, append that element to the value list corresponding to the current dictionary key.
  7. After the loop completes, print the final constructed dictionary ‘res‘.

Below is the implementation of the above approach:




# Initializing list
test_list = ["GFG-1", 4, 6, 7, 10, "GFG-2", 2, 3, "GFG-3", 9, 2, 4, 6]
 
# Initializing prefix
temp = "GFG"
 
# Initializing dictionary
res = {}
 
# Iterating through the list and appending the values to the dictionary
for i in test_list:
    if str(i).startswith(temp):
        res[i] = []
        key = i
    else:
        res[key].append(i)
 
# Printing result
print("The constructed dictionary : " + str(res))

Output
The constructed dictionary : {'GFG-1': [4, 6, 7, 10], 'GFG-2': [2, 3], 'GFG-3': [9, 2, 4, 6]}

Time Complexity: O(n), where ‘n’ is the number of elements in the list.
Auxiliary Space: O(n), where ‘n’ is the number of elements in the list, as we are creating a dictionary to store the elements of the list.

Method 4: Using loop + dictionary 

Approach:

  1. Initialize an empty dictionary, res.
  2. Initialize a variable key to an empty string.
  3. Loop through the test_list:
  4. If an element in the list starts with the prefix temp, update the key variable to the current element, and add an empty list to the dictionary with the current element as the key.
  5. If the current element is not a string and does not start with the prefix, append it to the list of the currentkey in the dictionary.
  6. Print the dictionary res.




test_list = ["GFG-1", 4, 6, 7, 10, "GFG-2", 2, 3, "GFG-3", 9, 2, 4, 6]
temp = "GFG"
res = {}
key = ""
 
for i in test_list:
    if isinstance(i, str) and i.startswith(temp):
        key = i
        res[key] = []
    else:
        res[key].append(i)
 
print("The constructed dictionary : " + str(res))

Output
The constructed dictionary : {'GFG-1': [4, 6, 7, 10], 'GFG-2': [2, 3], 'GFG-3': [9, 2, 4, 6]}

Time complexity: O(N), where n is the length of the input list.
Auxiliary space: O(N), as we need to store all the elements in the dictionary.

Method 5: Using list comprehension and slicing

Step-by-step approach:

Below is the implementation of the above approach:




# Python3 code to demonstrate working of
# Convert List to key-value list by prefix grouping
# Using list comprehension and slicing
 
# initializing list
test_list = ["GFG-1", 4, 6, 7, 10, "GFG-2", 2, 3, "GFG-3", 9, 2, 4, 6]
 
# printing original list
print("The original list : " + str(test_list))
 
# initializing prefix
temp = "GFG"
 
# slicing the list to get the indices where the prefix occurs
indices = [i for i, x in enumerate(test_list) if str(x).startswith(temp)]
 
# constructing the dictionary
res = {test_list[indices[i]]: test_list[indices[i]+1:indices[i+1]] if i<len(indices)-1 else test_list[indices[i]+1:] for i in range(len(indices))}
 
# Printing result
print("The constructed dictionary : " + str(res))

Output
The original list : ['GFG-1', 4, 6, 7, 10, 'GFG-2', 2, 3, 'GFG-3', 9, 2, 4, 6]
The constructed dictionary : {'GFG-1': [4, 6, 7, 10], 'GFG-2': [2, 3], 'GFG-3': [9, 2, 4, 6]}

Time complexity: O(n), where n is the length of the input list.
Auxiliary space: O(n), where n is the length of the input list. 


Article Tags :