Sometimes, while working with Python list we can have problems in which we need to perform grouping. There can be a particular problem in which we need to group consecutive occurring elements. Having solution to this problem is useful. Let’s discuss the certain way in which this can be done.
Method 1: Using groupby() + list comprehension
This task can be performed using the inbuilt groupby() offered by Python in an easy way. This can be coupled with list comprehension for logic combination and iteration.
Step-by-step approach:
- Import the groupby function from the itertools module.
- Initialize a list test_list with some values.
- Print the original list.
- Use groupby() function to group identical consecutive elements in test_list. This returns an iterator which returns a tuple for each group. The first element of the tuple is the key, which is the value of the element that is being grouped, and the second element is an iterator that returns the consecutive identical elements.
- Use a list comprehension to convert the iterator returned by groupby() into a list of lists, where each inner list represents a group of identical consecutive elements.
- Store the resulting list in the variable res.
- Print the resulting list.
Below is the implementation of the above approach:
Python3
# Python3 code to demonstrate working of # Identical Consecutive Grouping in list # using groupby() + list comprehension from itertools import groupby # initialize list test_list = [ 4 , 4 , 5 , 5 , 5 , 7 , 7 , 8 , 8 , 8 ] # printing original list print ( "The original list is : " + str (test_list)) # Identical Consecutive Grouping in list # using groupby() + list comprehension res = [ list (y) for x, y in groupby(test_list)] # printing result print ( "List after grouping is : " + str (res)) |
The original list is : [4, 4, 5, 5, 5, 7, 7, 8, 8, 8] List after grouping is : [[4, 4], [5, 5, 5], [7, 7], [8, 8, 8]]
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.
Method 2: Using a for loop and an if statement
You can achieve the same result by iterating through the list and checking if the current element is equal to the previous element. If it is, then add it to the current group. If it is not, then create a new group and add the current element to it.
Step-by-step approach:
- Initializes a list called test_list with some integer values.
- Prints the original list using the print() function and string concatenation.
- Creates two empty lists, res and curr_group.
- Loops through each element in test_list using a for loop, and uses the enumerate() function to get both the index and value of the current element.
- Checks whether the current element is the first element in the list (i.e. i == 0) or whether it is different from the previous element in the list (i.e. x != test_list[i-1]).
- If either of these conditions is true, the program starts a new group by creating a new list called curr_group with the current element, and appends curr_group to res.
- If neither of these conditions is true, the program adds the current element to the current group by appending it to curr_group.
- After all elements have been processed, the program prints the grouped list res using the print() function and string concatenation.
Below is the implementation of the above approach:
Python3
# Python3 code to demonstrate working of # Identical Consecutive Grouping in list # using for loop and if statement # initialize list test_list = [ 4 , 4 , 5 , 5 , 5 , 7 , 7 , 8 , 8 , 8 ] # printing original list print ( "The original list is : " + str (test_list)) # Identical Consecutive Grouping in list # using for loop and if statement res = [] curr_group = [] for i, x in enumerate (test_list): if i = = 0 or x ! = test_list[i - 1 ]: # start a new group curr_group = [x] res.append(curr_group) else : # add to current group curr_group.append(x) # printing result print ( "List after grouping is : " + str (res)) |
The original list is : [4, 4, 5, 5, 5, 7, 7, 8, 8, 8] List after grouping is : [[4, 4], [5, 5, 5], [7, 7], [8, 8, 8]]
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.
Method 3: Using NumPy’s split() function
Here’s another method that uses NumPy’s split() function to split the original list into subarrays of consecutive identical elements.
Python3
import numpy as np # initialize list test_list = [ 4 , 4 , 5 , 5 , 5 , 7 , 7 , 8 , 8 , 8 ] # convert list to numpy array test_array = np.array(test_list) # split array into sub-arrays where consecutive elements are not equal split_array = np.split(test_array, np.where(np.diff(test_array) ! = 0 )[ 0 ] + 1 ) # convert sub-arrays back to lists res = [ list (sub_array) for sub_array in split_array] # print result print ( "List after grouping is : " + str (res)) |
Output-
The original list is : [4, 4, 5, 5, 5, 7, 7, 8, 8, 8]
List after grouping is : [[4, 4], [5, 5, 5], [7, 7], [8, 8, 8]]
Time Complexity: The time complexity of this code is O(n) where n is the number of elements in the input list.
Auxiliary Space: The auxiliary space used by this code is O(n) where n is the number of elements in the input list.
Method 4: Using a recursive function to split the list into sublists of consecutive identical elements
This method uses a recursive function that splits the list into consecutive groups of identical elements by comparing each element with the first element of the list, and then recursively calling itself with the remaining elements of the list.
Python3
def split_consecutive_groups(lst): if not lst: return [] head = lst[ 0 ] tail = lst[ 1 :] group = [head] + [x for x in tail if x = = head] return [group] + split_consecutive_groups([x for x in tail if x ! = head]) # initialize list test_list = [ 4 , 4 , 5 , 5 , 5 , 7 , 7 , 8 , 8 , 8 ] # printing original list print ( "The original list is : " + str (test_list)) # Identical Consecutive Grouping in list # using recursive function res = split_consecutive_groups(test_list) # printing result print ( "List after grouping is : " + str (res)) |
The original list is : [4, 4, 5, 5, 5, 7, 7, 8, 8, 8] List after grouping is : [[4, 4], [5, 5, 5], [7, 7], [8, 8, 8]]
Time complexity: O(n^2), where n is the length of the input list.
Auxiliary space: O(n^2), as each recursive call generates a new sublist of identical elements, which is stored in memory until the final result is returned.
Method 5: Using itertools.groupby()
The itertools module in Python provides a groupby() function that groups consecutive identical elements of a list together. We can use this function to solve the given problem.
Step-by-step approach:
- Import the itertools module.
- Use the groupby() function to group consecutive identical elements of the input list.
- Convert the groupby object into a list of lists where each sublist contains consecutive identical elements.
- Return the list of sublists.
Below is the implementation of the above approach:
Python3
import itertools def split_consecutive_groups(lst): return [ list (group) for key, group in itertools.groupby(lst)] # initialize list test_list = [ 4 , 4 , 5 , 5 , 5 , 7 , 7 , 8 , 8 , 8 ] # printing original list print ( "The original list is : " + str (test_list)) # Identical Consecutive Grouping in list # using itertools.groupby() res = split_consecutive_groups(test_list) # printing result print ( "List after grouping is : " + str (res)) |
The original list is : [4, 4, 5, 5, 5, 7, 7, 8, 8, 8] List after grouping is : [[4, 4], [5, 5, 5], [7, 7], [8, 8, 8]]
Time complexity: O(n)
Auxiliary space: O(n) (for the output list)
Method 6: Using stack
- Create an empty list called ‘result’
- Create an empty stack called ‘stack’
- Loop through each element ‘elem’ in the input list ‘lst’:
- If ‘stack’ is empty or ‘stack[-1]’ is equal to ‘elem’, append ‘elem’ to ‘stack’
- Else, pop all elements from ‘stack’ and append them to ‘result’, and then append ‘elem’ to ‘stack’
Pop all elements from ‘stack’ and append them to ‘result’ - Return ‘result’
Python3
def split_consecutive_groups(lst): result = [] stack = [] for elem in lst: if not stack or stack[ - 1 ] = = elem: stack.append(elem) else : result.append(stack[:]) stack.clear() stack.append(elem) result.append(stack[:]) return result test_list = [ 4 , 4 , 5 , 5 , 5 , 7 , 7 , 8 , 8 , 8 ] res = split_consecutive_groups(test_list) print (res) |
[[4, 4], [5, 5, 5], [7, 7], [8, 8, 8]]
Time complexity: O(n), where n is the length of the input list, since we only loop through the list once.
Auxiliary Space: O(n), since we use a stack to keep track of the consecutive identical elements.