Python获取列表重复元素索引范围:求内置函数或实现方法
Unfortunately, there isn't a Python built-in function that directly gives you the index ranges of consecutive elements like you're requesting. collections.Counter is useful for counting how many times each element appears, but it doesn't track where those elements are located in the list.
Luckily, we can build this functionality efficiently using itertools.groupby—a tool designed specifically for grouping consecutive elements that share the same value. Here's a step-by-step implementation:
Solution Code
from itertools import groupby def index_range(lst): result = {} # Pair each element with its index, then group by the element value for value, grouped_items in groupby(enumerate(lst), key=lambda x: x[1]): # Extract all indices from the current consecutive group indices = [idx for idx, _ in grouped_items] # Create a range string (start-end) for this group range_str = f"{indices[0]}-{indices[-1]}" # Add to our result dictionary: append if the value already has ranges if value in result: result[value] += f", {range_str}" else: result[value] = range_str return result
How It Works
enumerate(lst): This adds the index to each element in your list, giving us pairs like(0, -1),(1, -1), etc.groupby(..., key=lambda x: x[1]): Groups these pairs by the element value (the second item in each tuple), so we get consecutive runs of the same element.- Extract indices: For each group, we pull out all the indices from the paired tuples. Since
groupbyonly groups consecutive elements, these indices form a continuous range. - Build range strings: For each group, the first index is the start of the range, and the last index is the end. We format this into a string like
"0-2". - Populate the dictionary: We add each range string to the corresponding key in our result dictionary. If the element appears in multiple non-consecutive runs, we append the new range string with a comma.
Testing with Your Sample
Let's try it with your list:
a = [-1,-1,-1,1,1,1,2,2,2,-1,-1,-1,1,1,1] print(index_range(a))
Output:
{-1: '0-2, 9-11', 1: '3-5, 12-14', 2: '6-8'}
This works for edge cases too—if an element only appears once, you'll get a range like "5-5", and non-consecutive runs of the same element each get their own range entry.
内容的提问来源于stack exchange,提问作者feroze waris

