Open In App

Python – Group concatenate Till K

Improve
Improve
Like Article
Like
Save
Share
Report

Given list of strings, perform concatenation in groups till K.

Input : test_list = [“Gfg”, “is”, “Best”, “”, “I”, “Love”, “”, “Gfg”], K = “” 
Output : [‘Gfg is Best’, ‘I Love’, ‘Gfg’] 
Explanation : Concatenated words with “” as new String separator. 

Input : test_list = [“Gfg”, “is”, “Best”, “”, “I”, “Love”], K = “” 
Output : [‘Gfg is Best’, ‘I Love’] 
Explanation : Concatenated words with “” as new String separator.

Method 1: Using loop + join() + list comprehension

This is a way in which this task can be performed. In this, we construct parts of strings into lists and then perform the join of individual lists using join() and list comprehension.

Python3




# Python3 code to demonstrate working of
# Group concatenate Till K
# Using loop + join() + list comprehension
 
# initializing lists
test_list = ["Gfg", "is", "Best", None, "I", "Love", None, "Gfg"]
 
# printing original list
print("The original list : " + str(test_list))
 
# initializing K
K = None
 
# all() to encapsulate whole logic into one expression
res = [[]]
for sub in test_list:
     
    # checking for K value, and performing append to
    # latest list
    if sub != K:
        res[-1].append(sub)
    else:
         
        # constructing new list if new group
        res.append([])
 
# Joining all groups
fin_res = [' '.join(ele) for ele in res]
 
# printing result
print("Concatenated Groups : " + str(fin_res))


Output

The original list : ['Gfg', 'is', 'Best', None, 'I', 'Love', None, 'Gfg']
Concatenated Groups : ['Gfg is Best', 'I Love', 'Gfg']

Time Complexity: O(n)
Space Complexity: O(n)

Method 2: Using itertools.groupby():

You can also solve this problem by using the itertools.groupby() function. This function groups the elements of a list based on a key function. In this case, the key function would be a lambda function that returns the value of the element if it is not None, and a unique value (such as an empty string) if the element is None. Then, you can join the elements of each group using the join() function and store them in a list using a list comprehension.

Python3




from itertools import groupby
 
# initializing lists
test_list = ["Gfg", "is", "Best", None, "I", "Love", None, "Gfg"]
 
# printing original list
print("The original list : " + str(test_list))
 
# initializing K
K = None
 
# defining key function for groupby
key_func = lambda x: '' if x is None else x
 
# using groupby to group elements of the list
groups = groupby(test_list, key_func)
 
# joining elements of each group and storing them in a list
fin_res = [' '.join(filter(None, list(g))) for k, g in groups]
 
# printing result
print("Concatenated Groups : " + str(fin_res))


Output

The original list : ['Gfg', 'is', 'Best', None, 'I', 'Love', None, 'Gfg']
Concatenated Groups : ['Gfg', 'is', 'Best', '', 'I', 'Love', '', 'Gfg']

Time complexity: O(n + k + m).

  • groupby() function has a time complexity of O(n), where n is the number of elements in the list.
  • The list comprehension iterates over the groups generated by groupby() and has a time complexity of O(k), where k is the number of groups.
  • The join() function has a time complexity of O(m), where m is the total number of characters in the strings of each group.
  • Therefore, the overall time complexity of Method 2 is O(n + k + m).

Space complexity: O(k + m).

  • The groupby() function generates the groups on the fly and does not use any extra memory, so it has a space complexity of O(1).
  • The list comprehension creates a new list of strings to store the concatenated groups, so its space complexity is O(k + m).
  • Therefore, the overall space complexity of Method 2 is O(k + m).

Method 3: Using itertools.takewhile() and itertools.dropwhile()

we first define a helper function remove_none() that takes a group of elements and removes the None values from the beginning and end of the group using itertools.takewhile() and itertools.dropwhile() functions respectively.

We then use itertools.groupby() function to group the elements based on the K value. We pass a lambda function to the key argument of itertools.groupby() that returns True if the element is equal to K and False otherwise. We then use a list comprehension to concatenate the groups and remove the None values using our helper function.

Finally, we print the result.

Python3




import itertools
 
# initializing lists
test_list = ["Gfg", "is", "Best", None, "I", "Love", None, "Gfg"]
 
# printing original list
print("The original list : " + str(test_list))
 
# initializing K
K = None
 
# function to remove None values
def remove_none(lst):
    return itertools.dropwhile(lambda x: x is None, itertools.takewhile(lambda x: x is not None, lst))
 
# group by K value and concatenate
res = [' '.join(remove_none(group)) for key, group in itertools.groupby(test_list, lambda x: x == K) if not key]
 
# printing result
print("Concatenated Groups : " + str(res))


Output

The original list : ['Gfg', 'is', 'Best', None, 'I', 'Love', None, 'Gfg']
Concatenated Groups : ['Gfg is Best', 'I Love', 'Gfg']

Time complexity: O(n), where n is the number of elements in the input list.
Auxiliary space: O(n), as we are creating new lists to store the groups and removing the None values. However, since we are using itertools functions, the memory usage is optimized, and it’s better than creating new lists using traditional list manipulation techniques

Method 4 : Using join()+split()+for loop

Approach

  1. Create a newlist replacing K in list with “*” and keeping remaining elements as it is
  2. Join the list of strings using join()
  3. Split the string by “*” using split() which results in a list
  4. Now list obtained contains concatenated groups, display the list

Python3




# Python3 code to demonstrate working of
# Group concatenate Till K
# initializing lists
test_list = ["Gfg", "is", "Best", None, "I", "Love", None, "Gfg"]
 
# printing original list
print("The original list : " + str(test_list))
 
# initializing K
K = None
v=[]
for i in test_list:
    if(i==K):
        v.append("*")
    else:
        v.append(i)
x="".join(v)
y=x.split("*")
# printing result
print("Concatenated Groups : " + str(y))


Output

The original list : ['Gfg', 'is', 'Best', None, 'I', 'Love', None, 'Gfg']
Concatenated Groups : ['GfgisBest', 'ILove', 'Gfg']

Time complexity: O(n), where n is the number of elements in the input list.
Auxiliary space: O(n), as we are creating new lists to store the groups and replacing the None values.

Method #5: Using the Recursive Method:

Approach:

  1. Define a function group_concat_recursive(lst, K):
  2. If K is not in lst, return a list with the original list as its only element. Otherwise, find the index of the first occurrence of K in last
  3. Split the list into two parts: the elements before K and the elements after K
  4. Recursively call group_concat_recursive on the second part to get a list of concatenated groups from the rest of the list
  5. Prepend the first part of the original list to the list obtained from step 5, and return the resulting list

Below is the implementation of the above approach:

Python3




def group_concat_recursive(lst, K):
    if K not in lst:
        return [''.join(lst)]
    else:
        index = lst.index(K)
        return [''.join(lst[:index])] + group_concat_recursive(lst[index+1:], K)
 
 
# Example Usage
test_list = ["Gfg", "is", "Best", None, "I", "Love", None, "Gfg"]
K = None
result = group_concat_recursive(test_list, K)
 
# Printing original list
print("The original list : " + str(test_list))
 
# Printing result
print("Concatenated Groups : " + str(result))


Output

The original list : ['Gfg', 'is', 'Best', None, 'I', 'Love', None, 'Gfg']
Concatenated Groups : ['GfgisBest', 'ILove', 'Gfg']

Time Complexity: The time complexity of the recursive implementation depends on the number of occurrences of K in the list. In the worst case, where K appears at every position in the list, the function needs to recursively split the list into smaller parts n times, where n is the length of the list. In each recursive call, the function needs to find the index of the first occurrence of K, which takes O(N) time in the worst case. Therefore, the overall time complexity of the recursive implementation is O(N2) in the worst case.

Space complexity: The space complexity of the recursive implementation depends on the maximum depth of the recursion, which is the number of occurrences of K in the list. In the worst case, where K appears at every position in the list, the function needs to recursively call itself n times, where n is the length of the list. Each recursive call creates a new list to store the elements between two occurrences of K. Therefore, the overall space complexity of the recursive implementation is O(N2) in the worst case. However, in practice, the space complexity is likely to be much lower, as K is unlikely to appear at every position in the list.

Method 6: Using the reduce() function

  1. Define the function group_concat_reduce(lst, delimiter) with two parameters: lst is the input list, and delimiter is the separator character.
  2. Define a nested function concat_groups(groups, element) that takes two parameters: groups is a list of concatenated groups so far, and element is the current element from the input list.
  3. Check if the current element is not equal to the delimiter. If so, check if the groups list is empty. If it is, append the current element to groups. Otherwise, concatenate the current element to the last group in groups.
  4. If the current element is equal to the delimiter, append an empty string to groups.
  5. Return the updated groups list from the concat_groups function.
  6. Use the reduce() function from the functools module to apply the concat_groups function to each element in the input list lst, starting with an empty list [].
  7. Return the final result, which is the list of concatenated groups.
  8. Test the function with an example input list test_list and a delimiter K, and print the original list and the concatenated groups.
  9. In the print statement for the concatenated groups, use the * operator to unpack the list and print the elements separated by commas.

Python3




from functools import reduce
 
 
def group_concat_reduce(lst, delimiter):
    def concat_groups(groups, element):
        if element != delimiter:
            if not groups:
                groups.append(element)
            else:
                groups[-1] += element
        else:
            groups.append('')
        return groups
    return reduce(concat_groups, lst, [])
 
 
# Example Usage
test_list = ["Gfg", "is", "Best", None, "I", "Love", None, "Gfg"]
K = None
result = group_concat_reduce(test_list, K)
 
# Printing original list
print("The original list : " + str(test_list))
 
# Printing result
print("Concatenated Groups : ", end="")
print(*result, sep=", ")


Output

The original list : ['Gfg', 'is', 'Best', None, 'I', 'Love', None, 'Gfg']
Concatenated Groups : GfgisBest, ILove, Gfg

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



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