Open In App

# Python | Retain K consecutive elements

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.