知道列表中是否存在值(列表中包含数百万个值)及其索引是什么的最快方法是什么?
我知道列表中的所有值都是唯一的,如本例所示。
我尝试的第一种方法是(在我的实际代码中为3.8秒):
a = [4,2,3,1,5,6]
if a.count(7) == 1:
b=a.index(7)
"Do something with variable b"
我尝试的第二种方法是(速度提高了2倍:实际代码为1.9秒):
a = [4,2,3,1,5,6]
try:
b=a.index(7)
except ValueError:
"Do nothing"
else:
"Do something with variable b"
堆栈溢出用户建议的方法(我的实际代码为2.74秒):
a = [4,2,3,1,5,6]
if 7 in a:
a.index(7)
在我的真实代码中,第一种方法耗时3.81秒,第二种方法耗时1.88秒。 这是一个很好的改进,但是:
我是使用Python /脚本的初学者,有没有更快的方法来做相同的事情并节省更多的处理时间?
我的应用程序更具体的说明:
在Blender API中,我可以访问粒子列表:
particles = [1, 2, 3, 4, etc.]
从那里,我可以访问粒子的位置:
particles[x].location = [x,y,z]
对于每个粒子,我通过搜索每个粒子位置来测试是否存在邻居:
if [x+1,y,z] in particles.location
"Find the identity of this neighbour particle in x:the particle's index
in the array"
particles.index([x+1,y,z])
#1楼
这不是代码,而是用于快速搜索的算法。
如果您要查找的列表和值都是数字,那么这很简单。 如果是字符串:请看底部:
- -让“ n”为列表的长度
- -可选步骤:如果需要元素索引,请向列表中添加第二列,其中元素的当前索引为(0至n-1)-稍后请参见
- 订购列表或列表的副本(.sort())
- 依次通过:
- 将您的数字与列表的第n / 2个元素进行比较
- 如果更大,则在索引n / 2-n之间再次循环
- 如果较小,则在索引0-n / 2之间再次循环
- 如果相同:您找到了
- 将您的数字与列表的第n / 2个元素进行比较
- 不断缩小列表的范围,直到找到它或只有2个数字(在您要查找的数字的下方和上方)
- 这将在最多19个步骤中找到1.000.000列表中的任何元素(准确地说是log(2)n)
如果您还需要号码的原始位置,请在第二个索引列中查找。
如果您的列表不是由数字组成的,则该方法仍然有效并且将是最快的,但是您可能需要定义一个可以比较/排序字符串的函数。
当然,这需要sorted()方法的投资,但是如果您继续重复使用同一列表进行检查,则可能值得这样做。
#2楼
听起来您的应用程序可能会受益于使用Bloom Filter数据结构的优势。
简而言之,布隆过滤器查询可以很快告诉您集合中是否绝对没有值。 否则,您可以进行较慢的查找,以获取列表中可能存在的值的索引。 因此,如果您的应用程序倾向于比“已找到”结果更频繁地获得“未找到”结果,则可以通过添加Bloom Filter来加快速度。
有关详细信息,Wikipedia很好地概述了布隆过滤器的工作方式,并且对“ python布隆过滤器库”的网络搜索将至少提供一些有用的实现。
#3楼
正如其他人所述,对于大型列表, in
可能会非常慢。 这是in
, set
和bisect
的性能比较。 请注意时间(以秒为单位)是对数刻度。