
本文介绍使用 python `collections.counter` 快速、准确地提取列表中所有重复元素,并保持其**首次成为重复项时的出现顺序**,适用于如 `[1,2,2,3,3,3,4,4,4,4] → [2,3,4]` 等典型场景。
原始递归实现存在两个关键缺陷:一是未去重,导致同一重复元素(如 2)在后续子列表中反复被识别并多次加入结果;二是未保证“首次重复”顺序——例如输入 [1,2,24,2,1] 中,1 在索引 0 出现、索引 4 再次出现,2 在索引 1 出现、索引 3 再次出现,因此 1 应先于 2 被加入结果,但原递归逻辑因遍历顺序与重复判定耦合,无法稳定维持该语义。
更优解是借助 collections.Counter 统计频次,再结合原列表的遍历顺序筛选出首次满足 count > 1 的元素。注意:Counter 本身不保证插入顺序(Python 3.7+ 字典已有序,Counter 继承自 dict,故其 items() 默认按首次出现顺序返回),但为确保逻辑清晰与兼容性,推荐显式按原列表顺序去重后过滤:
from collections import Counter
def find_duplicates(list_of_numbers):
# 统计频次
counts = Counter(list_of_numbers)
# 按原列表顺序遍历,对每个元素检查是否重复,且仅首次遇到时添加(避免重复添加)
seen = set()
result = []
for num in list_of_numbers:
if counts[num] > 1 and num not in seen:
result.append(num)
seen.add(num)
return result
# 测试用例
print(find_duplicates([1, 2, 2, 3, 3, 3, 4, 4, 4, 4])) # 输出: [2, 3, 4]
print(find_duplicates([1, 2, 24, 2, 1])) # 输出: [1, 2]✅ 优势说明:
- 时间复杂度 O(n),远优于递归方案的 O(n²);
- 逻辑清晰,避免递归栈溢出与重复添加问题;
- 严格保持“重复元素首次出现位置”的相对顺序;
- 兼容任意可哈希类型(数字、字符串、元组等)。
⚠️ 注意事项:
- 若输入含不可哈希类型(如字典、列表),需先转换或改用其他策略;
- 空列表或无重复列表将返回空列表 [],符合预期;
- 不建议强行复用原始递归思路——它本质难以兼顾顺序性与效率,应转向更合适的工具链。
综上,Counter + 有序遍历去重 是解决该问题的标准、健壮且高效的 Python 实践方式。










