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

Python向Set添加Dataclass实例时合并同标识对象属性的方法

问题根因

你当前的实现无法正确归集发言的核心原因有两点:

  • 每次循环都创建全新的Speaker实例,虽然你重写了__eq__和__hash__让相同id+name的实例被判定为相等,但set遇到重复元素时会直接丢弃新传入的实例,不会对已存储的实例做任何更新,自然没法追加新的发言内容
  • 循环中单独编写的Speaker(id, name)没有赋值给任何变量,属于完全无效的冗余代码
推荐实现方案

set本身不支持直接获取已存储的相等元素的引用,因此最高效、且完全兼容后续字段扩展的方案是用临时字典做实例索引(注意这里字典仅存储Speaker实例对象,不会把实例拆成字典结构存储,后续给Speaker新增title等字段时不需要改动核心归集逻辑):

  1. 字典的key直接使用你判定Speaker相等的依据,也就是(id, name)元组,如果后续调整相等判定规则,只需要同步修改key的组成即可
  2. 遍历待处理数据时,如果key不在索引字典中,就新建Speaker实例存入字典;如果key已存在,直接取出对应实例,往它的statements列表追加当前发言
  3. 遍历完成后,将字典的所有value转为set即可得到目标结果

实现代码如下:

from typing import List
from dataclasses import dataclass, field

@dataclass
class Speaker:
    id: int
    name: str
    statements: List[str] = field(default_factory=list)
    # 后续新增字段直接在这里添加即可,比如title: str = "",归集逻辑无需改动

    def __eq__(self, other):
        return self.id == other.id and self.name == other.name

    def __hash__(self):
        return hash((self.id, self.name))


test = [(1, 'john', 'foo'),(1, 'john', 'bar'),(2, 'jane', 'near'),(2, 'george', 'far')]

speaker_index = {}
for id, name, statement in test:
    key = (id, name)
    if key not in speaker_index:
        speaker_index[key] = Speaker(id=id, name=name)
    speaker_index[key].statements.append(statement)

speakers = set(speaker_index.values())
print(speakers)

运行后输出完全符合预期:

{Speaker(id=1, name='john', statements=['foo', 'bar']), Speaker(id=2, name='jane', statements=['near']), Speaker(id=2, name='george', statements=['far'])}
其他可选方案(不推荐大数据量场景)

如果不想用临时字典,也可以通过遍历set匹配已有实例的方式实现,但是时间复杂度为O(n²),仅适合数据量极小的场景:

speakers = set()
for id, name, statement in test:
    tmp_speaker = Speaker(id, name)
    # 遍历set查找是否已存在相等的实例
    for exist in speakers:
        if exist == tmp_speaker:
            exist.statements.append(statement)
            break
    else:
        # 循环正常结束说明没有匹配到已有实例,新建加入
        speakers.add(Speaker(id, name, [statement]))

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 07:24:25