Python如何移除嵌套列表中被其他元素包含的重复短列表
Python实现前缀子序列嵌套列表去重
需求说明
现有如下嵌套列表:
result = [['A', 100], ['A', 200], ['A', 300], ['A', 100, 'WERKS'], ['A', 200, 'MATNR'], ['A', 300, 'RESNR']]
去重规则:若短列表是另一个长列表的前缀子序列(例如['A', 100]是['A', 100, 'WERKS']的前缀),则移除短列表,仅保留最长的完整列表。
预期输出结果:
[['A', 100, 'WERKS'], ['A', 200, 'MATNR'], ['A', 300, 'RESNR']]
注:原示例中后3个列表内的A未加字符串引号属于书写笔误,实际运行需补全引号,否则会触发变量未定义的报错。
实现思路
- 先把所有子列表按长度降序排序,优先处理最长的子列表,保证最终保留的是最长版本
- 遍历排序后的子列表,逐个检查当前子列表是不是已经被加入结果集的某个长列表的前缀:如果是,说明当前短列表需要被剔除,直接跳过;如果不是,就把它加入结果集
- 前缀判断直接用列表切片对比实现,不需要依赖第三方库,写法简洁易读
完整可运行代码
def deduplicate_prefix_nest_list(input_list): # 按子列表长度从长到短排序 sorted_items = sorted(input_list, key=lambda x: len(x), reverse=True) keep_items = [] for item in sorted_items: item_len = len(item) need_remove = False # 遍历已保留的长列表,检查当前item是不是它的前缀 for kept in keep_items: # 已保留的列表长度不大于当前item,不可能存在前缀匹配,直接跳过 if len(kept) <= item_len: continue if kept[:item_len] == item: need_remove = True break if not need_remove: keep_items.append(item) return keep_items # 测试验证 if __name__ == "__main__": result = [['A', 100], ['A', 200], ['A', 300], ['A', 100, 'WERKS'], ['A', 200, 'MATNR'], ['A', 300, 'RESNR']] result2 = deduplicate_prefix_nest_list(result) print(result2) # 输出结果与预期一致:[['A', 100, 'WERKS'], ['A', 200, 'MATNR'], ['A', 300, 'RESNR']]
补充说明
该逻辑同时兼容常规去重场景:如果存在两个完全相同的子列表,只会保留一个;如果两个子列表长度相同但内容不同,会全部保留,符合通用使用预期。如果数据量特别大,可以把已保留的列表按前缀做哈希索引优化性能,日常业务场景下当前写法的执行效率完全足够。
内容的提问来源于stack exchange,提问作者Owen
相关产品推荐
相关产品推荐

