Python – Grouped Consecutive Range Indices of Elements

Sometimes we need to group consecutive occurrences of elements in a list and track their index ranges. Python provides an efficient approach using defaultdict and groupby from the itertools module to identify consecutive elements and map their start and end indices.

Understanding Grouped Consecutive Range Indices

When elements appear consecutively in a list, we can group them and track their index ranges. For example, in the list [1, 1, 2, 3, 3, 3], element 1 appears at indices 0-1, element 2 at index 2, and element 3 at indices 3-5.

Example with Consecutive Elements

Let's create a list with consecutive duplicate elements to better demonstrate the concept ?

from itertools import groupby
from collections import defaultdict

# List with consecutive duplicate elements
my_list = [10, 10, 20, 30, 30, 30, 40, 40]

print("The list is:")
print(my_list)

my_index = 0
my_result = defaultdict(list)

for key, sub in groupby(my_list):
    element_count = len(list(sub))
    start_index = my_index
    end_index = my_index + element_count - 1
    my_result[key].append((start_index, end_index))
    my_index += element_count

print("The resultant dictionary is:")
for key, ranges in my_result.items():
    print(f"{key}: {ranges}")
The list is:
[10, 10, 20, 30, 30, 30, 40, 40]
The resultant dictionary is:
10: [(0, 1)]
20: [(2, 2)]
30: [(3, 5)]
40: [(6, 7)]

Example with Non-Consecutive Elements

Here's an example where elements are not consecutive, so each gets its own single-element range ?

from itertools import groupby
from collections import defaultdict

my_list = [63, 12, 84, 91, 52, 39, 25, 27, 20, 11, 0, 9]

print("The list is:")
print(my_list)

my_index = 0
my_result = defaultdict(list)

for key, sub in groupby(my_list):
    element_count = len(list(sub))
    start_index = my_index
    end_index = my_index + element_count - 1
    my_result[key].append((start_index, end_index))
    my_index += element_count

print("The resultant dictionary is:")
for key, ranges in my_result.items():
    print(f"{key}: {ranges}")
The list is:
[63, 12, 84, 91, 52, 39, 25, 27, 20, 11, 0, 9]
The resultant dictionary is:
63: [(0, 0)]
12: [(1, 1)]
84: [(2, 2)]
91: [(3, 3)]
52: [(4, 4)]
39: [(5, 5)]
25: [(6, 6)]
27: [(7, 7)]
20: [(8, 8)]
11: [(9, 9)]
0: [(10, 10)]
9: [(11, 11)]

How It Works

  • groupby() groups consecutive identical elements together

  • defaultdict(list) creates a dictionary with empty lists as default values

  • For each group, we calculate the start and end indices of consecutive elements

  • The tuple (start_index, end_index) represents the range where each element appears consecutively

Multiple Consecutive Groups

Elements can appear in multiple separate consecutive groups ?

from itertools import groupby
from collections import defaultdict

# Element 'A' appears in two separate consecutive groups
my_list = ['A', 'A', 'B', 'C', 'A', 'A', 'A', 'D']

print("The list is:")
print(my_list)

my_index = 0
my_result = defaultdict(list)

for key, sub in groupby(my_list):
    element_count = len(list(sub))
    start_index = my_index
    end_index = my_index + element_count - 1
    my_result[key].append((start_index, end_index))
    my_index += element_count

print("The resultant dictionary is:")
for key, ranges in my_result.items():
    print(f"'{key}': {ranges}")
The list is:
['A', 'A', 'B', 'C', 'A', 'A', 'A', 'D']
The resultant dictionary is:
'A': [(0, 1), (4, 6)]
'B': [(2, 2)]
'C': [(3, 3)]
'D': [(7, 7)]

Conclusion

Using groupby() with defaultdict efficiently groups consecutive elements and tracks their index ranges. This approach is perfect for analyzing sequential patterns in data where you need to know both the element values and their positions.

Updated on: 2026-03-26T01:44:07+05:30

277 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements