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

如何在Python中实现类似Gurobi的高效检索tuplelist类

类似Gurobi tuplelist类的实现方案

核心原理

Gurobi的tuplelist高效的核心是提前构建倒排索引避免全表扫描,具体实现逻辑如下:

  • 继承Python原生list类,保留列表所有原生操作能力,无需重写基础列表方法
  • 内部维护倒排索引字典,键为(字段位置, 字段值)二元组,值为所有符合该位置等于该值的元组在列表中的下标集合
  • select方法通过匹配多个字段的倒排索引取交集,直接定位符合条件的元素下标,查询效率仅和匹配结果数量相关,不受总数据量影响

完整实现代码

class TupleList(list):
    def __init__(self, iterable=None):
        super().__init__()
        self._index = {}  # 倒排索引存储结构:(位置, 值) -> 对应元素下标集合
        self._tuple_length = None
        if iterable:
            for item in iterable:
                self.append(item)
    
    def append(self, item):
        # 校验元素类型为元组
        if not isinstance(item, tuple):
            raise TypeError("TupleList仅支持存储元组类型元素")
        # 校验所有元组长度统一
        if self._tuple_length is None:
            self._tuple_length = len(item)
        elif len(item) != self._tuple_length:
            raise ValueError(f"所有元组长度必须统一为{self._tuple_length}")
        # 元素加入列表
        current_idx = len(self)
        super().append(item)
        # 更新倒排索引
        for pos, val in enumerate(item):
            index_key = (pos, val)
            if index_key not in self._index:
                self._index[index_key] = set()
            self._index[index_key].add(current_idx)
    
    def select(self, *args):
        # 校验查询参数数量和元组长度匹配
        if len(args) != self._tuple_length:
            raise ValueError(f"查询参数数量需与元组长度一致,应为{self._tuple_length}个")
        # 收集所有非通配条件的匹配下标集合
        match_collections = []
        for pos, condition in enumerate(args):
            if condition is None:  # None为通配符,匹配该位置所有值
                continue
            # 支持单值匹配或多值匹配
            target_values = {condition} if not isinstance(condition, (list, tuple, set)) else set(condition)
            # 合并该位置所有目标值对应的下标
            pos_match_set = set()
            for val in target_values:
                pos_match_set.update(self._index.get((pos, val), set()))
            match_collections.append(pos_match_set)
        # 无有效查询条件则返回全量数据
        if not match_collections:
            return self.copy()
        # 取所有条件集合的交集得到最终匹配下标
        result_indices = set.intersection(*match_collections)
        # 按原列表顺序返回匹配结果
        return [self[idx] for idx in sorted(result_indices)]

使用示例

# 初始化TupleList实例
tl = TupleList([
    (1, 2, 3),
    (1, 4, 5),
    (2, 2, 6),
    (1, 2, 7),
    (3, 4, 8)
])

# 示例1:查询第一个位置为1,第二个位置为2,第三个位置任意的元组
print(tl.select(1, 2, None))
# 输出:[(1, 2, 3), (1, 2, 7)]

# 示例2:查询第二个位置为4,第三个位置为5或8的元组
print(tl.select(None, 4, [5, 8]))
# 输出:[(1, 4, 5), (3, 4, 8)]

# 支持原生列表的所有操作,新增元素会自动更新索引
tl.append((2, 4, 9))
print(tl.select(2, None, None))
# 输出:[(2, 2, 6), (2, 4, 9)]

效率说明

该实现和Gurobi官方tuplelist的核心逻辑完全一致,在十万级以上元组的查询场景下,查询效率比原生列表推导高两个数量级以上。如果需要支持pop、remove等列表操作,只要对应重写方法同步更新倒排索引即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 18:15:02