Open In App

Convert List to Key – Value List by Prefix Grouping – Python

Last Updated : 21 Jan, 2025
Comments
Improve
Suggest changes
Like Article
Like
Report

Given a list, we are required to convert it into a dictionary of consecutive key-value pairs where the key is a string (starting with a prefix) and the values are grouped by that prefix until the next key with the same prefix is encountered.
For example: We have a list ["GFG-1", 4, 6, "GFG-2", 3, "GFG-3", 9, 2] and s = "GF" then the output will be {'GFG-1': [4, 6], 'GFG-2': [3], 'GFG-3': [9, 2]}

Using groupby() and startswith()

In this method we use groupby() from itertools along with a lambda function that checks if the element starts with a given prefix, groupby() groups the elements based on the prefix and converts the list into key-value pairs where the key is the prefix and the values are the corresponding elements.

Python
from itertools import groupby

li = ["GFG-1", 4, 6, 7, 10, "GFG-2", 2, 3, "GFG-3", 9, 2, 4, 6]
s = "GFG"
res = {}

# Extracting result from grouped by prefix
for key, val in groupby(li, lambda ele: str(ele).startswith(s)):
    # checking for existing key
    if key:
        k = next(val)
    else:
        res[k] = list(val)
        
print("dictionary : " + str(res))

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

Explanation: groupby(li, lambda ele: str(ele).startswith(s)) divides the list into groups based on whether elements start with “GFG” or not. The key will be True for “GFG” prefixed elements and False for numbers while val contains those grouped elements.

Using defaultdict

In this method, we use a defaultdict with list as the default value type to group elements in the list by their prefix. Each time an element starts with the prefix, it is treated as a key. Subsequent non-key elements are added to the list under the last valid key.

Python
from collections import defaultdict

li = ["GFG-1", 4, 6, 7, 10, "GFG-2", 2, 3, "GFG-3", 9, 2, 4, 6]
s = "GFG"
res = defaultdict(list)

# iterating through the list and appending the values to the dictionary
for i in li:
    if str(i).startswith(s):
        key = i
    else:
        res[key].append(i)

print("dictionary", dict(res))

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

Using Loop and Dictionary

In this method we will use a for loop to iterate through the list and for each element we check if it is a string using the isinstance() method and whether it starts with the given prefix using the startswith() method. If both conditions are true, we treat the current element as a key and add it to the dictionary with an empty list as its value but if the element is not a string or does not start with the prefix we append it to the list associated with the current key.

Python
li = ["GFG-1", 4, 6, 7, 10, "GFG-2", 2, 3, "GFG-3", 9, 2, 4, 6]
s = "GFG"
res = {}
key = ""

for i in li:
    if isinstance(i, str) and i.startswith(s):
        key = i  
        res[key] = [] 
    else:
        res[key].append(i)  

print("dictionary:", res)

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

Using List Comprehension and Slicing

In this method we try to identify indices of prefix elements using a list comprehension and then use dictionary comprehension to slice the list dynamically, grouping elements between indices for intermediate keys and the rest for the last key.

Python
li = ["GFG-1", 4, 6, 7, 10, "GFG-2", 2, 3, "GFG-3", 9, 2, 4, 6]
s = "GFG"

# Get indices of prefix occurrences
indices = [i for i, x in enumerate(li) if str(x).startswith(s)]

# Construct dictionary using slicing
res = {li[indices[i]]: li[indices[i]+1:indices[i+1]] if i < len(indices)-1 else li[indices[i]+1:] for i in range(len(indices))}

print("dictionary:", res)

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

Explanation:

  • indices = [i for i, x in enumerate(li) if str(x).startswith(s)] is used to collect indices where elements start with the prefix s ("GFG").
  • res = {li[indices[i]]: li[indices[i]+1:indices[i+1]] if i < len(indices)-1 else li[indices[i]+1:] for i in range(len(indices))} is used to build a dictionary where keys are the prefix elements and values are slices of the list between consecutive prefixes or from the last prefix to the end.


Next Article

Similar Reads