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

如何移除包含列表字段的dataclass对象列表中的重复元素

问题根因

frozen=True仅限制你不能重新给dataclass的字段赋值,不会改变字段本身的类型特性,list属于可变不可哈希类型,因此dataclass自动生成的__hash__方法无法正常工作,导致用set、dict.fromkeys等依赖哈希的方法去重时报错。

可选解决方案

方案1:替换为不可变序列类型(优先推荐)

如果业务场景不需要修改该字段的内容,直接把字段类型从List[str]替换为Tuple[str, ...]即可,无需额外自定义逻辑,直接复用dataclass自动生成的哈希和相等判断逻辑。
示例代码:

from dataclasses import dataclass
from typing import Tuple

@dataclass(eq=True, frozen=True)
class TestClass:
    field1: str
    field_list: Tuple[str, ...] # 改为Tuple类型

# 构造对象&去重示例
obj1 = TestClass("test", ("a", "b"))
obj2 = TestClass("test", ("a", "b"))
obj3 = TestClass("test2", ("c", "d"))

unique_objs = list(set([obj1, obj2, obj3])) # 运行正常

方案2:自定义__hash__方法

如果必须保留List类型字段,自行实现哈希方法,计算哈希时将列表转为可哈希的元组即可:

from dataclasses import dataclass
from typing import List

@dataclass(eq=True, frozen=True)
class TestClass:
    field1: str
    field_list: List[str]

    def __hash__(self) -> int:
        # 将list转为tuple参与哈希计算
        return hash((self.field1, tuple(self.field_list)))

# 去重逻辑正常运行
obj1 = TestClass("test", ["a", "b"])
obj2 = TestClass("test", ["a", "b"])
obj3 = TestClass("test2", ["c", "d"])
unique_objs = list(set([obj1, obj2, obj3]))

注意:该方案有使用前提,使用过程中不能修改field_list内部的元素。frozen=True仅禁止给字段重新赋值,列表本身的可变性没有被限制,如果修改了列表内的元素,已经生成的哈希值会失效,导致set、dict等结构出现逻辑错误。

内容的提问来源于stack exchange,提问作者T-Dawg

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 04:45:03