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

Python:如何高效从列表中提取满足__eq__()的类实例?

解决方案

核心问题在于列表的线性查找效率太低(时间复杂度O(n)),当列表规模增长时性能会急剧下降。最优方案是用**字典(dict)**做索引,把需要匹配的attr1作为键,对应的实例作为值,这样查找操作的时间复杂度是O(1),完全解决效率问题。

具体实现方式

1. 一次性构建索引字典

如果你的列表是静态的(不会频繁增删实例),可以直接把列表转换成字典:

from collections import defaultdict

# 假设你的自定义类是这样的
class MyClass:
    def __init__(self, attr1, attr2):
        self.attr1 = attr1
        self.attr2 = attr2
    
    def __eq__(self, other):
        return isinstance(other, MyClass) and self.attr1 == other.attr1

# 原列表
original_list = [MyClass("a", 1), MyClass("b", 2), MyClass("a", 3)]

# 构建索引字典:如果多个实例有相同attr1,用list存所有匹配实例
inst_index = defaultdict(list)
for inst in original_list:
    inst_index[inst.attr1].append(inst)

# 查找匹配inst1的实例
inst1 = MyClass("a", 99)
if inst1.attr1 in inst_index:
    # 获取所有attr1匹配的实例
    matched_insts = inst_index[inst1.attr1]
    # 如果确定只有一个匹配,直接取第一个
    target_inst = matched_insts[0]
    print(target_inst.attr2)  # 输出 1

2. 动态维护索引字典

如果列表是动态变化的(需要频繁添加/删除实例),那么每次操作列表时同步更新字典,避免重复构建:

# 初始化空列表和索引字典
inst_list = []
inst_index = defaultdict(list)

# 添加实例的方法
def add_inst(inst):
    inst_list.append(inst)
    inst_index[inst.attr1].append(inst)

# 删除实例的方法
def remove_inst(inst):
    if inst in inst_list:
        inst_list.remove(inst)
        inst_index[inst.attr1].remove(inst)
        # 如果该attr1下没有实例了,可以删除键节省空间
        if not inst_index[inst.attr1]:
            del inst_index[inst.attr1]

# 使用示例
inst_a1 = MyClass("a", 1)
add_inst(inst_a1)
add_inst(MyClass("a", 3))

# 查找
inst1 = MyClass("a", 99)
if inst1.attr1 in inst_index:
    matched_insts = inst_index[inst1.attr1]
    # 处理匹配到的实例

3. 保留列表顺序同时快速查找

如果必须保留原列表的顺序(比如需要按插入顺序遍历),这种“列表+字典索引”的组合方案完全适用,既满足顺序需求,又能实现O(1)的查找效率。

为什么不用列表遍历?

当列表规模达到万级甚至十万级时,线性遍历的时间开销会非常明显,而字典的哈希查找几乎不受数据规模影响,是处理这类查找需求的标准解决方案。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 00:37:08