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

如何高效向列表添加唯一整数并维持其升序有序状态?

动态有序唯一整数列表的高效实现方案(百万级数据)

需求

需要实现一个动态构建的列表,逐个添加值时必须满足以下两个条件:

  • 列表内所有元素唯一
  • 列表始终保持升序排序

处理的数据规模为百万级整数,列表需要支持动态增删操作,要求实现方案具备极高的效率。

排除的低效方案

sorted(set(lst))完全不符合需求,原因如下:

  1. 列表并非预先生成,后续需要频繁进行增删修改
  2. 该方案本身效率极低,每次修改后重复执行排序和去重会消耗大量时间,无法处理百万级数据

尝试过的自定义实现及问题

我尝试过一种实现思路:同时维护一个与列表元素一致的set,通过set快速检查元素是否存在,仅当元素不存在时才添加到列表,同时更新两者以保证唯一性;通过二分查找计算插入索引来维持列表的有序性。

自定义实现代码如下:

from bisect import bisect

class Sorting_List:
    def __init__(self):
        self.data = []
        self.unique = set()

    def add(self, n):
        if n in self.unique:
            return

        self.unique.add(n)
        if not self.data:
            self.data.append(n)
            return
        if n > self.data[-1]:
            self.data.append(n)
        elif n < self.data[0]:
            self.data.insert(0, n)
        elif len(self.data) == 2:
            self.data.insert(1, n)
        else:
            self.data.insert(bisect(self.data, n), n)

但该方案存在明显缺陷:需要同时维护set和列表,内存利用率低,且时间效率并非最优。

性能测试结果

我针对不同实现方案做了多组性能测试:

成员检查性能对比

测试线性查找、二分查找与set成员检查的性能差异,测试代码:

from timeit import timeit

def test(n):
    setup = f'''from bisect import bisect
from random import choice
c = choice(range({n//2}, {n}))
numbers = list(range({n}))'''
    linear = timeit('c in numbers', setup) / 1e6
    binary = timeit('bisect(numbers, c) - 1 == c ', setup) / 1e6
    return linear, binary

测试结论:

  • 列表的成员检查是线性查找,当元素数量≤12时速度优于二分查找,但元素数量增多后,性能远低于二分查找
  • set的成员检查速度远快于二分查找,线性查找的速度最慢

具体测试数据:

In [188]: lst = list(range(256))

In [189]: s = set(lst)

In [190]: %timeit 199 in s
42.5 ns ± 0.946 ns per loop (mean ± std. dev. of 7 runs, 10,000,000 loops each)

In [191]: %timeit bisect(lst, 199)
159 ns ± 1.38 ns per loop (mean ± std. dev. of 7 runs, 10,000,000 loops each)

In [192]: %timeit 199 in lst
2.53 µs ± 31.7 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each)

第三方有序集合库测试

测试对象为SortedSet和SortedList,测试数据为1048576个随机整数:

In [243]: numbers = random.choices(range(4294967295), k=1048576)

In [244]: sl = Sorting_List()

In [245]: ss = SortedSet()

In [246]: %timeit for i in numbers: ss.add(i)
306 ms ± 8.55 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

In [247]: %timeit for i in numbers: sl.add(i)
---------------------------------------------------------------------------
KeyboardInterrupt                         Traceback (most recent call last)
...

In [248]: sls = SortedList()

In [249]: s = set()

In [250]: %%timeit
     ...: for i in numbers:
     ...:     if i not in s:
     ...:         sls.add(i)
     ...:         s.add(i)
145 ms ± 3.24 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

In [251]: len(numbers)
Out[251]: 1048576

测试结论:

  • 百万级元素场景下,自定义实现效率极低,甚至无法完成测试
  • SortedSet和SortedList可正常处理百万级数据
  • SortedList搭配set做成员检查是目前时间效率最高的方案,但内存利用率较低
  • 单独使用SortedList做成员检查(内部为线性查找)效率极低:
In [252]: sls = SortedList()

In [253]: %%timeit
     ...: for i in numbers:
     ...:     if i not in sls:
     ...:         sls.add(i)
1.93 s ± 16.5 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

寻求更优方案

目前需要找到更高效的实现方案,可以使用第三方库的有序集合类,但必须保证在百万级数据场景下的性能。


内容的提问来源于stack exchange,提问作者Ξένη Γήινος

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 17:22:10