Open In App

Python – Extract range of Consecutive Similar elements ranges from string list

Last Updated : 09 May, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Given a list, extract a range of consecutive similar elements.

Input : test_list = [2, 3, 3, 3, 8, 8] 
Output : [(2, 0, 0), (3, 1, 3), (8, 4, 5)] 
Explanation : 2 occurs from 0th to 0th index, 3 from 1st to 3rd index.
Input : test_list = [3, 3, 3] 
Output : [(3, 0, 3)] 
Explanation : 3 from 0th to 3rd index. 

Approach: Using loop

This is a brute way to tackle this problem. In this, we loop for each element and get a similar element range. These are traced and appended in the list accordingly with elements.

Steps:

  1. Initialize a list test_list with integer values.
  2. Print the original list.
  3. Initialize an empty list res to store the results.
  4. Initialize a variable idx to 0.
  5. While the value of idx is less than the length of the test_list:
    a. Set the variable strt_pos equal to the current value of idx.
    b. Set the variable val equal to the value at index idx in test_list.
    c. While the value of idx is less than the length of test_list and the value at index idx is equal to val, increment idx by 1.
    d. Set the variable end_pos equal to idx – 1.
    e. Append the tuple (val, strt_pos, end_pos) to the list res.
  6. Print the elements with their range in the format [ele, strt_pos, end_pos] using the res list.

Python3




# Python3 code to demonstrate working of
# Consecutive Similar elements ranges
# Using loop
 
# Initializing list
test_list = [2, 3, 3, 3, 8, 8, 6, 7, 7]
 
# Printing original list
print("The original list is : " + str(test_list))
 
res = []
idx = 0
 
while idx < (len(test_list)):
    strt_pos = idx
    val = test_list[idx]
 
    # Getting last position
    while (idx < len(test_list) and test_list[idx] == val):
        idx += 1
    end_pos = idx - 1
 
    # Appending in format [element, start, end position]
    res.append((val, strt_pos, end_pos))
 
# Printing result
print("Elements with range : " + str(res))


Output

The original list is : [2, 3, 3, 3, 8, 8, 6, 7, 7]
Elements with range : [(2, 0, 0), (3, 1, 3), (8, 4, 5), (6, 6, 6), (7, 7, 8)]

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

Method 2: using Python’s built-in itertools.groupby() function

Approach:

  1. Import itertools module.
  2. Initialize the list.
  3. Use groupby() function to group the elements based on their value.
  4. Convert the groupby object to a list of tuples and store them in res.
  5. For each tuple in res, extract the key (i.e., the value of the similar elements), the start index, and the end index using the built-in functions.
  6. Append a tuple of (key, start index, end index) to the result list.
  7. Print the original list and the elements with their range.

Python3




# Python3 code to demonstrate working of
# Consecutive Similar elements ranges
# Using Python's built-in itertools.groupby() method
 
import itertools
 
# Initializing list
test_list = [2, 3, 3, 3, 8, 8, 6, 7, 7]
 
# Printing original list
print("The original list is : " + str(test_list))
 
# Grouping similar elements
# using itertools.groupby() method
res = []
for k, g in itertools.groupby(test_list):
 
    group = list(g)
    start_index = test_list.index(group[0])
    end_index = start_index + len(group) - 1
 
    res.append((k, start_index, end_index))
 
# Printing the result
print("Elements with range : " + str(res))


Output

The original list is : [2, 3, 3, 3, 8, 8, 6, 7, 7]
Elements with range : [(2, 0, 0), (3, 1, 3), (8, 4, 5), (6, 6, 6), (7, 7, 8)]

Time Complexity: O(n), where n is the length of the list.
Auxiliary Space: O(n), to store the result list.

Method 3: Using the numpy library 

Step-by-step approach:

  • Import the numpy library.
  • Convert the given list to a numpy array using numpy.array() method.
  • Calculate the difference between consecutive elements using the numpy.diff() method and concatenate a 0 at the beginning to capture the starting index of each group.
  • Find the indices where the difference is non-zero using the numpy.nonzero() method.
  • Calculate the start and end indices for each group by iterating through the indices obtained in step 4.
  • Create a list of tuples containing the group value and its start and end indices.
  • Return the resulting list.

Python3




import numpy as np
 
def consecutive_similar_elements_ranges(test_list):
    # Convert list to numpy array
    arr = np.array(test_list)
     
    # Calculate difference between consecutive elements
    diff = np.concatenate(([0], np.diff(arr)))
     
    # Find indices where difference is non-zero
    idx = np.nonzero(diff)[0]
     
    # Iterate through indices and calculate start and end indices for each group
    res = []
    for i in range(len(idx)):
        start = idx[i]
        end = idx[i+1]-1 if i+1 < len(idx) else len(test_list)-1
        res.append((test_list[start], start, end))
     
    # Check if the first element is missing from the result
    if len(res) == 0 or res[0][0] != test_list[0]:
        res.insert(0, (test_list[0], 0, 0))
     
    return res
 
# Example usage
test_list = [2, 3, 3, 3, 8, 8, 6, 7, 7]
print(consecutive_similar_elements_ranges(test_list))


OUTPUT :
[(2, 0, 0), (3, 1, 3), (8, 4, 5), (6, 6, 6), (7, 7, 8)]

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



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads