检查一个值是否存在于一个非常大的列表的最快方法是什么?


当前回答

这不是代码,而是快速搜索的算法。

如果您的列表和您正在寻找的值都是数字,这是相当简单的。如果字符串:看底部:

-Let "n" be the length of your list -Optional step: if you need the index of the element: add a second column to the list with current index of elements (0 to n-1) - see later Order your list or a copy of it (.sort()) Loop through: Compare your number to the n/2th element of the list If larger, loop again between indexes n/2-n If smaller, loop again between indexes 0-n/2 If the same: you found it Keep narrowing the list until you have found it or only have 2 numbers (below and above the one you are looking for) This will find any element in at most 19 steps for a list of 1.000.000 (log(2)n to be precise)

如果您还需要您的数字的原始位置,请在第二索引列中查找。

如果您的列表不是由数字组成的,该方法仍然有效,并且将是最快的,但您可能需要定义一个可以比较/排序字符串的函数。

当然,这需要使用sorted()方法,但如果您不断重用相同的列表进行检查,那么这样做可能是值得的。

其他回答

请注意,in操作符不仅测试相等性(==),还测试恒等式(is),列表的in逻辑大致相当于以下内容(实际上是用C而不是Python编写的,至少在CPython中是这样):

对于s中的元素: 如果元素是目标: #快速检查身份意味着相等 还真 如果element == target: #慢速检查实际相等 还真 返回假

在大多数情况下,这个细节是无关紧要的,但在某些情况下,它可能会让Python新手感到惊讶,例如numpy。NAN具有不等于自身的不寻常性质:

>>> import numpy
>>> numpy.NAN == numpy.NAN
False
>>> numpy.NAN is numpy.NAN
True
>>> numpy.NAN in [numpy.NAN]
True

为了区分这些不寻常的情况,你可以使用任何(),比如:

>>> lst = [numpy.NAN, 1 , 2]
>>> any(element == numpy.NAN for element in lst)
False
>>> any(element is numpy.NAN for element in lst)
True 

注意,使用any()的列表的in逻辑将是:

any(element is target or element == target for element in lst)

然而,我应该强调这是一个边缘情况,对于绝大多数情况,in操作符是高度优化的,当然正是你想要的(无论是对列表还是对集合)。

7 in a

最清晰最快的方法。

您也可以考虑使用一个集合,但是从列表中构造该集合所花费的时间可能比快速成员测试所节省的时间要多。唯一确定的方法就是做好基准测试。(这也取决于你需要什么操作)

你可以把你的物品放在一个集合里。设置查找非常有效。

Try:

s = set(a)
if 7 in s:
  # do stuff

在注释中,你说你想获取元素的索引。不幸的是,集合没有元素位置的概念。另一种方法是对列表进行预先排序,然后在每次需要查找元素时使用二分搜索。

def check_availability(element, collection: iter):
    return element in collection

使用

check_availability('a', [1,2,3,4,'a','b','c'])

我相信这是知道所选值是否在数组中的最快方法。

这不是代码,而是快速搜索的算法。

如果您的列表和您正在寻找的值都是数字,这是相当简单的。如果字符串:看底部:

-Let "n" be the length of your list -Optional step: if you need the index of the element: add a second column to the list with current index of elements (0 to n-1) - see later Order your list or a copy of it (.sort()) Loop through: Compare your number to the n/2th element of the list If larger, loop again between indexes n/2-n If smaller, loop again between indexes 0-n/2 If the same: you found it Keep narrowing the list until you have found it or only have 2 numbers (below and above the one you are looking for) This will find any element in at most 19 steps for a list of 1.000.000 (log(2)n to be precise)

如果您还需要您的数字的原始位置,请在第二索引列中查找。

如果您的列表不是由数字组成的,该方法仍然有效,并且将是最快的,但您可能需要定义一个可以比较/排序字符串的函数。

当然,这需要使用sorted()方法,但如果您不断重用相同的列表进行检查,那么这样做可能是值得的。