You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python中如何对对象列表去重?要求仅i==j时对象引用相等

在Python中基于对象身份(is)对可变对象列表去重

我太懂这个痛点了——当你要对可变/不可哈希对象列表按对象身份(也就是is判断相等)去重时,常规的set()方法直接歇菜,毕竟像set这种可变类型没法哈希。而且你要的不是值相等,是完全同一个对象实例:只有当list_of_objects[i] is list_of_objects[j]时才认为是重复项,对吧?

核心思路:用id()获取对象的唯一标识

Python里每个对象实例在其生命周期内都有一个唯一的id,这相当于我们能拿到一个“隐形指针”,不管对象是不是可哈希,都能用它来判断是不是同一个实例。基于这个思路,我们可以直接实现去重。

方法1:自定义函数(清晰易懂,兼容所有Python版本)

这个方法遍历列表,记录已经见过的对象id,只保留首次出现的实例:

def deduplicate_by_identity(obj_list):
    seen_ids = set()
    unique_objects = []
    for obj in obj_list:
        obj_id = id(obj)
        if obj_id not in seen_ids:
            seen_ids.add(obj_id)
            unique_objects.append(obj)
    return unique_objects

测试示例1:

a = {1,2,3}
b = {4,5,6}
cur_dict = {1:a, 2:a, 3:a, 4:b, 5:b, 6:b}
duplicated_clusters = list(cur_dict.values())
print(deduplicate_by_identity(duplicated_clusters))  # 输出 [{1, 2, 3}, {4, 5, 6}]

测试示例2:

a = {1,2,3}
b = {4,5,6}
c = {1,2,3}
duplicated_clusters = [a,a,b,b,c,c]
print(deduplicate_by_identity(duplicated_clusters))  # 输出 [{1,2,3}, {4,5,6}, {1,2,3}],等价于[a,b,c]

方法2:一行代码实现(Python 3.7+,利用字典插入顺序)

从Python 3.7开始,字典会保留键的插入顺序,我们可以用字典推导式快速去重:

deduplicated_clusters = list({id(obj): obj for obj in duplicated_clusters}.values())

原理和上面的函数完全一致:用对象的id作为字典的键(自动去重),最后取字典的值就是唯一的对象实例列表。

对比你的临时方案

这个方法比你之前维护名字映射字典的方案更直接,不需要额外的中间字典,直接操作对象本身,减少了代码的复杂度和出错概率。

注意事项

  • id()的唯一性只在对象的生命周期内有效:如果某个对象被垃圾回收了,它的id可能会被复用,但在处理列表的过程中,只要列表里的对象都还存活,id就是完全可靠的。

内容的提问来源于stack exchange,提问作者Dau Zi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 12:37:36