Python中快速删除List内自定义类重复对象及追加前判重的方法
方案说明
首先要明确Python默认是按内存地址判断类实例是否相等,要实现业务属性维度的去重,有两类常见实现思路:
前置准备(可选,不需要改类源码可以跳过)
如果可以修改MyClass的源码,优先给类加上相等判断和哈希方法,后续判断逻辑会更简洁:
from typing import Optional class MyClass: def __init__(self, string_a: Optional[str] = None, string_b: Optional[str] = None): self.string_a = string_a self.string_b = string_b # 定义业务相等规则:两个属性完全一致则视为重复实例 def __eq__(self, other): if not isinstance(other, MyClass): return False return self.string_a == other.string_a and self.string_b == other.string_b # 配合集合做哈希校验用,哈希值由两个业务属性共同生成 def __hash__(self): return hash((self.string_a, self.string_b))
方案1:已有列表快速去重(保留首次出现顺序,O(n)时间复杂度)
正好满足你移除第三次追加的重复实例的需求,不需要改动之前的追加逻辑:
- 如果已经改了
MyClass的实现,直接用实例做去重标记:
seen = set() test_clist = [item for item in test_clist if item not in seen and not seen.add(item)]
- 如果不能改
MyClass的源码,直接用属性拼接唯一键判断:
seen = set() test_clist = [item for item in test_clist if (key := (item.string_a, item.string_b)) not in seen and not seen.add(key)]
方案2:追加元素前提前判断(避免后续还要做一次去重,适合边生成实例边入库的场景)
- 改了
MyClass的情况:
from typing import List test_clist: List[MyClass] = [] seen = set() def append_unique(item: MyClass): if item not in seen: seen.add(item) test_clist.append(item) # 调用示例 append_unique(MyClass("hello", "world")) append_unique(MyClass("hello", "")) append_unique(MyClass("hello", "world")) # 重复实例会被拦截,不会加入列表 append_unique(MyClass(None, "world"))
- 不能改
MyClass的情况:
from typing import List test_clist: List[MyClass] = [] seen = set() def append_unique(item: MyClass): key = (item.string_a, item.string_b) if key not in seen: seen.add(key) test_clist.append(item)
注:你提供的示例代码存在两处笔误:一开始定义的变量名是test_list,后续追加用的是test_clist,最后一行append语句少了右括号,实际运行时注意修正。
内容的提问来源于stack exchange,提问作者cdub
相关产品推荐
相关产品推荐

