加速列表中的查找项(通过Python)

加速列表中的查找项(通过Python),python,performance,list,Python,Performance,List,我有一个非常大的列表,我必须对这个列表进行大量的查找。 更具体地说,我处理一个大的(>11GB)文本文件以进行处理,但有些项目会多次出现,我只能在它们出现时首先处理它们。 如果模式出现,我将对其进行处理,并将其放入列表中。如果该项再次出现,我将在列表中检查它,如果是,则我将其传递给process,如下所示: [...] if boundary.match(line): if closedreg.match(logentry): closedthreads.append(th

我有一个非常大的列表,我必须对这个列表进行大量的查找。 更具体地说,我处理一个大的(>11GB)文本文件以进行处理,但有些项目会多次出现,我只能在它们出现时首先处理它们。 如果模式出现,我将对其进行处理,并将其放入列表中。如果该项再次出现,我将在列表中检查它,如果是,则我将其传递给process,如下所示:

[...]
if boundary.match(line):
    if closedreg.match(logentry):
       closedthreads.append(threadid)
    elif threadid in closedthreads:
        pass
    else:
[...]
代码本身远远不是最优的。我的主要问题是“closedthreads”列表包含数百万项,而整个操作开始变得越来越慢。 我认为在每次append()之后对列表进行排序(或使用“排序列表”对象)可能会有所帮助,但我不确定这一点。
什么是最优雅的解决方案?

您可以简单地使用一个集合或哈希表来标记给定的id是否已经出现。它应该可以解决添加和查找项目的时间复杂性为O(1)的问题。

使用集合而不是列表将为您提供O(1)的查找时间,尽管可能有其他方法可以优化这一点,从而更好地处理您的特定数据

closedthreads = set() 
# ...

if boundary.match(line):
    if closedreg.match(logentry):
       closedthreads.add(threadid)
    elif threadid in closedthreads:
        pass
    else:

您需要保留订单吗

如果没有-使用一套

如果您这样做-使用订购的信息通信技术。OrderedDict允许您存储与之相关的值(例如,流程结果)


但是。。。是否需要保留原始值?如果您确实这样做了(或者购买了大量内存!),您可以查看“dbm”模块,或者不存储实际文本,而是存储SHA-1摘要,或者类似的内容。如果您只想确保不运行同一个元素两次,这可能会起作用。

我猜线程ID可能比它的SHA1散列短(尽管OP没有提供足够的信息),并且散列操作本身的计算成本太高。是的,这是真的-出于某种原因,我以为原来的东西是弦。在这种情况下,它实际上可能不会慢很多,甚至可能更快(因为要检查项目是否在集合中,您必须同时调用
\uuuuuu hash\uuuuuu
\uuuuuuu eq\uuuu
,并且字符串相等对长字符串的影响不一定很小)…谢谢这个示例。(我接受了另一个答案,因为它更快。):(对不起,伙计,下一次,正如到目前为止的答案所表明的那样,了解更多关于“threadid”的信息会很有帮助:它是哪种类型,如果值受到某种限制……最后,你需要一些快速查找,因此需要进行哈希,在某些情况下,制作你自己的哈希函数可能是一种方法;领域知识会有所帮助。threadid是一个简单的整数。(我正在处理大量mysql_slow.log文件,以便在使用percona回放的服务器上重新运行它们。为了加快回放过程,我必须关闭最后出现在日志上的线程。然后,接受的答案可能会很好。如果仍然存在速度问题,那么,是时候仔细查看这些数字了。或者更确切地说,是解决问题的时候了。)e实际问题以不同的方式解决。:)