如何移除列表列表中跨列表一致重复位置的重复元素并保留结构
问题
如何找出列表的列表中所有子列表元素均为重复项的共同位置,并移除这些重复元素?
详细描述
我有一个列表的列表(list of lists),其中各子列表的顺序保持一致,每个子列表内存在若干重复元素。我希望移除这些重复元素,但需保留每个子列表的结构——即若某个子列表中索引0、1、2的元素均为重复项,需移除其中两个,但同时要从所有其他子列表中移除相同索引的元素以维持顺序结构。但关键是,其他子列表中索引0、1、2的元素未必是重复项,因此仅当所有子列表中该组索引的元素均为重复项时,才执行移除操作。
示例
原列表的列表:
L = [ [1,1,1,3,3,2,4,6,6], [5,5,5,4,5,6,5,7,7], [9,9,9,2,2,7,8,10,10] ]
处理后期望得到:
L_new = [ [1,3,3,2,4,6], [5,4,5,6,5,7], [9,2,2,7,8,10] ]
可见索引1、2和8被移除,因为它们在所有子列表中均属于重复元素的位置;而索引3、4未被移除,因为并非所有子列表中该位置的元素都是重复项。
现有思路
我目前的思路(但认为并非最优,故寻求帮助):
def check_duplicates_in_same_position(arr_list): check_list = [] for arr in arr_list: duplicate_positions_list = [] positions = {} for i in range(len(arr)): item = arr[i] if item in positions: positions[item].append(i) else: positions[item] = [i] duplicate_positions = {k: v for k, v in positions.items() if len(v) > 1} for _, item in duplicate_positions.items(): duplicate_positions_list.append(item) check_list.append(duplicate_positions_list) return check_list
该函数返回一个嵌套列表,其中每个元素是包含若干子列表的列表,这些子列表存储对应子列表中重复元素的索引,例如:
[[[0, 1, 2], [3, 4], [7, 8]], [[0, 1, 2, 4, 6], [7, 8]], [[0, 1, 2], [3, 4], [7, 8]]]
我接下来想通过比较这些列表,找出如索引1、2、8这类所有子列表共有的重复位置并移除。
解决方案
核心思路
- 对每个子列表,标记重复元素组中非首次出现的索引为待移除候选
- 通过集合交集操作,筛选出所有子列表共同的待移除索引
- 统一过滤所有子列表,移除这些共同索引对应的元素
实现代码
def process_duplicate_positions(arr_list): # 生成每个子列表的待移除索引集合 remove_candidates = [] for arr in arr_list: first_occurrence = {} to_remove = set() for idx, val in enumerate(arr): if val in first_occurrence: to_remove.add(idx) else: first_occurrence[val] = idx remove_candidates.append(to_remove) # 找出所有子列表共同的待移除索引 if not remove_candidates: return arr_list common_remove = remove_candidates[0] for s in remove_candidates[1:]: common_remove.intersection_update(s) # 过滤所有子列表 result = [] for arr in arr_list: filtered = [val for idx, val in enumerate(arr) if idx not in common_remove] result.append(filtered) return result # 测试示例 L = [ [1,1,1,3,3,2,4,6,6], [5,5,5,4,5,6,5,7,7], [9,9,9,2,2,7,8,10,10] ] L_new = process_duplicate_positions(L) print(L_new)
代码说明
- 生成待移除候选:遍历每个子列表,用字典记录元素首次出现的索引,后续重复出现的索引加入待移除集合
- 筛选共同待移除索引:利用集合交集,找出所有子列表都标记为待移除的索引(示例中的1、2、8)
- 过滤元素:遍历每个子列表,仅保留不在共同待移除索引中的元素,得到最终结果
内容的提问来源于stack exchange,提问作者Pronitron
相关产品推荐
相关产品推荐

