检查列表中是否存在值的最快方法

我正在寻找最快的方法来了解列表中是否存在一个值(一个包含数百万个值的列表)以及它的索引是什么? 我知道列表中的所有值都是独特的,就像我的例子。

我尝试的第一种方法是(在我的真实代码中为3.8秒):

a = [4,2,3,1,5,6]

if a.count(7) == 1:
    b=a.index(7)
    "Do something with variable b"

我尝试的第二种方法是(快两倍:我的真实代码为1.9秒):

a = [4,2,3,1,5,6]

try:
    b=a.index(7)
except ValueError:
    "Do nothing"
else:
    "Do something with variable b"

来自Stackoverflow用户的建议方法(2.74秒,在我的真实代码上):

a = [4,2,3,1,5,6]
if 7 in a:
    a.index(7)

在我的真实代码中,第一个方法需要3.81秒,第二个方法需要1.88秒。 这是一个很好的改进,但是:

我是一名Python /脚本编程的初学者,我想知道是否存在最快的方式来执行相同的操作并节省更多的处理时间?

我的应用程序更具体的说明:

在搅拌器的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 particles in x:the index 
    of the particles array"
    particles.index([x+1,y,z])

7 in a

最清晰和最快速的方式来做到这一点。

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


正如其他人指出, in可以为大型列表非常慢。 下面是的演出一些比较insetbisect 。 请注意,时间(以秒为单位)以对数为单位。

在这里输入图像描述

测试代码:

import random
import bisect
import matplotlib.pyplot as plt
import math
import time

def method_in(a,b,c):
    start_time = time.time()
    for i,x in enumerate(a):
        if x in b:
            c[i] = 1
    return(time.time()-start_time)   

def method_set_in(a,b,c):
    start_time = time.time()
    s = set(b)
    for i,x in enumerate(a):
        if x in s:
            c[i] = 1
    return(time.time()-start_time)

def method_bisect(a,b,c):
    start_time = time.time()
    b.sort()
    for i,x in enumerate(a):
        index = bisect.bisect_left(b,x)
        if index < len(a):
            if x == b[index]:
                c[i] = 1
    return(time.time()-start_time)

def profile():
    time_method_in = []
    time_method_set_in = []
    time_method_bisect = []

    Nls = [x for x in range(1000,20000,1000)]
    for N in Nls:
        a = [x for x in range(0,N)]
        random.shuffle(a)
        b = [x for x in range(0,N)]
        random.shuffle(b)
        c = [0 for x in range(0,N)]

        time_method_in.append(math.log(method_in(a,b,c)))
        time_method_set_in.append(math.log(method_set_in(a,b,c)))
        time_method_bisect.append(math.log(method_bisect(a,b,c)))

    plt.plot(Nls,time_method_in,marker='o',color='r',linestyle='-',label='in')
    plt.plot(Nls,time_method_set_in,marker='o',color='b',linestyle='-',label='set')
    plt.plot(Nls,time_method_bisect,marker='o',color='g',linestyle='-',label='bisect')
    plt.xlabel('list size', fontsize=18)
    plt.ylabel('log(time)', fontsize=18)
    plt.legend(loc = 'upper left')
    plt.show()

a = [1,2,3,4,'a','b','c']
return 'a' in a

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

链接地址: http://www.djcxy.com/p/70689.html

上一篇: Fastest way to check if a value exist in a list

下一篇: Is there a simple way to delete a list element by value?