从混合嵌套列表中提取唯一子列表的Python技术问题
解决嵌套列表中提取唯一子列表的问题
我明白你遇到的困扰了——直接用abc=[] for x in pool: if x not in abc: abc.append(x)这种普通循环根本行不通,核心原因有两个:
- 你的数据集是多层嵌套的列表,原循环只会遍历第一层元素,没法深入提取内层的子列表;
- 列表是可变对象,虽然可以用
==比较内容,但直接用in判断嵌套结构时不仅效率低,还会漏掉深层的子列表。
下面我们分两步来解决这个问题:先把所有层级的子列表都提取出来,再对这些子列表去重。
步骤1:递归提取所有子列表
先写一个递归函数,遍历整个嵌套结构,把所有最底层的子列表(也就是里面不再嵌套列表的项,比如[1,2,39]、[4,14,63,65]这类)全部收集起来:
def extract_all_sublists(nested_list): result = [] for item in nested_list: if isinstance(item, list): # 判断当前列表是否还嵌套了其他列表 has_nested = any(isinstance(sub_item, list) for sub_item in item) if has_nested: # 有嵌套就递归处理内层 result.extend(extract_all_sublists(item)) else: # 没有嵌套就直接加入结果 result.append(item) return result
步骤2:对提取的子列表去重
因为列表是可变对象,没法直接用集合去重,我们可以先把每个子列表转换成元组(元组是可哈希的,能被集合识别),去重后再转回列表:
# 你的原始数据集 pool = [[1, 2, 39], [1, 2, 39], [3], [[3], [4, 14, 63, 65], [66, 68, 82, 94]], [[5, 8, 31, 34], [36, 37, 42, 44], [55]], [6, 91], [[7, 35, 60, 71], [73, 83, 95, 98]], [[5, 8, 31, 34], [36, 37, 42, 44], [55]], [9, 72], [[10, 22, 30, 32], [38, 51, 56, 87], [89, 92]], [11], [12], [13, 90], [[4, 14, 63, 65], [66, 68, 82, 94]]] # 提取所有层级的子列表 all_sublists = extract_all_sublists(pool) # 保持原顺序去重(Python 3.7+可用,依赖字典的插入顺序特性) unique_sublists = [] seen = set() for sublist in all_sublists: tuple_version = tuple(sublist) if tuple_version not in seen: seen.add(tuple_version) unique_sublists.append(sublist) # 打印最终结果 print(unique_sublists)
运行这段代码后,就能得到你期望的输出:
[[1, 2, 39], [3], [4, 14, 63, 65], [66, 68, 82, 94], [5, 8, 31, 34], [36, 37, 42, 44], [55], [6, 91], [7, 35, 60, 71], [73, 83, 95, 98], [9, 72], [10, 22, 30, 32], [38, 51, 56, 87], [89, 92], [11], [12], [13, 90]]
补充说明
- 递归函数可以处理任意深度的嵌套列表,不管你的数据集嵌套几层都能精准提取到最底层的子列表;
- 如果不需要保持子列表的出现顺序,直接用
set(tuple(s) for s in all_sublists)去重会更高效,之后再转回列表即可。
内容的提问来源于stack exchange,提问作者Muhammad Wasif




