Open In App

Python | Retain K consecutive elements

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

Sometimes while working with data, we can have a problem in which we need to select some of the elements that occur K times consecutively. This problem can occur in many domains. Let’s discuss certain ways in which this problem can be solved. 

Method #1 : Using groupby() + list comprehension 

This task can be performed using above functionalities. In this, we group all the numbers that are occurring K consecutively. We iterate the list using list comprehension. 

Python3




# Python3 code to demonstrate working of
# Retain K consecutive elements
# using groupby() + list comprehension
 
from itertools import groupby
 
# Initialize list
test_list = [1, 1, 4, 5, 5, 6, 7, 7, 8]
 
# Printing original list
print("The original list : " + str(test_list))
 
# Initialize K
K = 2
 
# Retain K consecutive elements
# using groupby() + list comprehension
res = [i for i, j in groupby(test_list) if len(list(j)) == K]
 
# Printing result
print("The K consecutive elements are : " + str(res))


Output : 

The original list : [1, 1, 4, 5, 5, 6, 7, 7, 8]
The K consecutive elements are : [1, 5, 7]

Time complexity : O(N)
Space complexity : O(K)

Method #2: Using list comprehension + slice() + groupby()

This task can also be performed using the above functions. In this, we just perform grouping in a similar way as above but the way we extract consecutive elements is by slice(). 

Python3




# Python3 code to demonstrate working of
# Retain K consecutive elements
# using groupby() + list comprehension + islice()
from itertools import groupby, islice
 
# Initializing list
test_list = [1, 1, 4, 5, 5, 6, 7, 7, 8]
 
# Printing original list
print("The original list : " + str(test_list))
 
# initialize K
K = 2
 
# Retain K consecutive elements
# using groupby() + list comprehension + islice()
res = [i for i, j in groupby(test_list) if len(list(islice(j, 0, K))) == K]
 
# Printing result
print("The K consecutive elements are : " + str(res))


Output : 

The original list : [1, 1, 4, 5, 5, 6, 7, 7, 8]
The K consecutive elements are : [1, 5, 7]

Time complexity : O(n)
Auxiliary Space: O(n)

Method 3: Using for loop

Algorithm:

  1. Initialize the original list and the value of K.
  2. Initialize an empty result list res.
  3. Loop through the elements of the original list from the first index to the (n-K)th index.
  4. Check if all the elements in the sublist of size K starting from the current index are the same or not.
  5. If they are the same, add the elements to the res list.
  6. Convert the res list to a set to remove any duplicates and then convert it back to a list.
  7. Print the final list as the result.
     

Python3




# Initialize list
test_list = [1, 1, 4, 5, 5, 6, 7, 7, 8]
 
# Printing original list
print("The original list : " + str(test_list))
 
# Initialize K
K = 2
 
# Retain K consecutive elements
# using a for loop
res = []
for i in range(len(test_list) - K + 1):
    if len(set(test_list[i:i+K])) == 1:
        res.extend(test_list[i:i+K])
res=list(set(res))
 
# Printing result
print("The K consecutive elements are : " + str(res))
 
# This code contributed by tvsk


Output

The original list : [1, 1, 4, 5, 5, 6, 7, 7, 8]
The K consecutive elements are : [1, 5, 7]

Time complexity: O(n-K), where n is the length of the original list.
Auxiliary space: O(K), where K is the size of the sublist being checked.

Method #4: Using a sliding window approach with deque

This approach maintains a deque of size K, which slides over the list to check consecutive elements. 

Python3




from collections import deque
 
# Initialize list
test_list = [1, 1, 4, 5, 5, 6, 7, 7, 8]
 
# Initialize K
K = 2
 
# Initialize deque with first K elements
d = deque(test_list[:K])
 
# Initialize result list
res = []
 
# Iterating over the list starting from index K
for i in range(K, len(test_list)):
    # check if all elements in the deque are equal
    if len(set(d)) == 1:
        res.extend(d)
    # remove the first element from the deque
    d.popleft()
    # add the next element to the deque
    d.append(test_list[i])
     
# Checking the last K elements in the deque
if len(set(d)) == 1:
    res.extend(d)
     
# Removing duplicates from the result list
res = list(set(res))
 
# Printing result
print("The K consecutive elements are : " + str(res))


Output

The K consecutive elements are : [1, 5, 7]

Time complexity: O(n), where n is the length of the input list. 
Auxiliary space: O(K), as we only store a deque of size K at any given time.

Method #5: Using numpy.diff():

Steps:

  1. Define the list and K value.
  2. Calculate the differences between K consecutive elements in the list using the np.diff() method.
  3. Find the indices where the difference is 0 using np.where() method.
  4. Extract the sublists of length K starting from the found indices.
  5. Combine all sublists into a single list.
  6. Remove any duplicates in the resulting list.
  7. Return the list of K consecutive elements.

Python3




import numpy as np
 
test_list = [1, 1, 4, 5, 5, 6, 7, 7, 8]
K = 2
 
# Printing original list
print("The original list : " + str(test_list))
 
diffs = np.diff(test_list, n=K-1)
indices = np.where(diffs == 0)[0]
 
res = []
 
for i in indices:
    res.extend(test_list[i:i+K])
res = list(set(res))
print("The K consecutive elements are : " + str(res))
 
# This code is contributed by Vinay pinjala.


Output:

The original list : [1, 1, 4, 5, 5, 6, 7, 7, 8]
The K consecutive elements are : [1, 5, 7]

Time complexity: O(n), where n is the length of the input list test_list. This is because the np.diff function and the subsequent np.where function take O(n) time, and the loop that extracts the K consecutive elements takes O(k) time, where k is the length of the output list.
Auxiliary space: O(n) because the diffs and indices arrays each require O(n) space, and the res list may also grow to O(n) in the worst case.

Method #6: Using the itertools module with islice() function.

Steps:

  1. We use itertools.islice() to create a sliding window of size K on the test_list.
  2. We check if all elements in the window are the same using the all() function.
  3. If all elements are the same, we extend res with the window.
  4. We remove duplicates from the result using the set() function.
  5. Finally, we convert res back to a list to maintain the order of the elements.

Python3




import itertools
 
# initialize list
test_list = [1, 1, 4, 5, 5, 6, 7, 7, 8]
 
# printing original list
print("The original list : " + str(test_list))
 
# initialize K
K = 2
 
# Retain K consecutive elements using itertools
res = []
for window in itertools.islice(zip(*(test_list[i:]
                                     for i in range(K))), len(test_list) - K + 1):
    if all(x == window[0] for x in window):
        res.extend(window)
 
# remove duplicates from the result
res = list(set(res))
 
# printing result
print("The K consecutive elements are : " + str(res))


Output

The original list : [1, 1, 4, 5, 5, 6, 7, 7, 8]
The K consecutive elements are : [1, 5, 7]

Time complexity: O(N*K) where N is the length of the input list and K is the size of the sliding window.
Auxiliary space: O(N) since the sliding window can hold up to N/K elements at any given time.

METHOD 7:Using re.

APPROACH:

This program takes a list of integers and a value k as input. It then finds all runs of k consecutive integers in the list, and returns them as a new list.

ALGORITHM:

1. Convert the input list to a string.
2. Construct a regular expression to find all runs of k consecutive digits in the string.
3. Use the re.findall() function to find all matches of the regular expression in the string.
4. Convert the matches back to integers and return the result.

Python3




import re
 
def retain_k_consecutive_elements(lst, k):
    # Convert the list to a string
    s = ''.join(str(x) for x in lst)
     
    # Find all runs of k consecutive characters
    regex = r'(\d)\1{{{}}}(?!\1)'.format(k-1)
    matches = re.findall(regex, s)
     
    # Convert the matches back to integers and return the result
    return [int(c) for c in ''.join(matches)]
 
lst = [1, 1, 4, 5, 5, 6, 7, 7, 8]
k = 2
print("The original list: ", lst)
print("The K consecutive elements: ", retain_k_consecutive_elements(lst, k))


Output

The original list:  [1, 1, 4, 5, 5, 6, 7, 7, 8]
The K consecutive elements:  [1, 5, 7]

Time Complexity:
The time complexity of this algorithm depends on the length of the input list and the value of k. The most time-consuming step is the regular expression search, which has a time complexity of O(n), where n is the length of the input string. Since the input list is converted to a string, the time complexity of this program is also O(n).

Space Complexity:
The space complexity of this algorithm depends on the length of the input list and the number of matches found by the regular expression search. The input list is converted to a string, which requires O(n) space. The regular expression search creates a list of matches, which requires additional space proportional to the number of matches. Therefore, the space complexity of this program is O(n+m), where n is the length of the input list and m is the number of matches found by the regular expression search.



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

Similar Reads