Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/304.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/dart/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在python中是否有更快的方法检查值是否在集合中?_Python - Fatal编程技术网

在python中是否有更快的方法检查值是否在集合中?

在python中是否有更快的方法检查值是否在集合中?,python,Python,我想维护一个字符串列表,并不断检查列表中是否有不同的变量 我正在做的是: li=[one,two,three] for x in different_x_values: if(x in li): print 'yes' 有没有比在li中使用x检查某个字符串是否在其他字符串集合中更快的方法?我相信您已经得到了答案,这是为了完整性。出于好奇,我对上面提到的方法进行了测试,结果如下 大小=主列表的大小 设置时间:使用s1和s2的时间 setintersectiontime:使用交叉操作的

我想维护一个字符串列表,并不断检查列表中是否有不同的变量

我正在做的是:

li=[one,two,three]
for x in different_x_values:
  if(x in li):
    print 'yes'

有没有比在li中使用
x检查某个字符串是否在其他字符串集合中更快的方法?

我相信您已经得到了答案,这是为了完整性。出于好奇,我对上面提到的方法进行了测试,结果如下

大小=主列表的大小
设置时间:使用s1和s2的时间
setintersectiontime:使用交叉操作的时间
暴力时间:暴力时间

尺寸=1000
setoptime:0:00:00.001000
setintersectiontime:0:00:00.001000
暴力时间:0:00:00.005000

尺寸=10000
setoptime:0:00:00.001000
setintersectiontime:0:00:00.010000
暴力时间:0:00:00.367000

尺寸=100000
setoptime:0:00:00.001000
setintersectiontime:0:00:00.115000
暴力时间:0:00:35.444000

方法1(setoptime)可以轻松获胜。如果您想查看,请看下面的代码

import timeit
import datetime
def getList(size):
    s=[]
    for i in range(size):
        s.append(str(i))
    return s

def getSubList(size):
    s=[]
    for i in range(size/2):
        s.append(str(i))
    return s

def testSet(size):
    s=set(getList(size))
    sublist=set(getSubList(size))
    list(s&sublist)


def testIntersection(size):
    s=set(getList(size))
    sublist=set(getSubList(size))
    list(s.intersection(sublist))

def bruteForce(size):
    s=getList(size)
    sublist=getSubList(size)
    final=[]
    for elem in sublist:
        try:
            if s.index(elem)!=-1:
                final.append(elem)
        except ValueError:
            pass
currentsize=1000
for i in range(3):
    t1=datetime.datetime.now()
    testSet(1000)
    t2=datetime.datetime.now()
    testIntersection(currentsize)
    t3=datetime.datetime.now()
    bruteForce(currentsize)
    t4=datetime.datetime.now()
    print "Size="+str(currentsize)
    print "setoptime:"+str(t2-t1)
    print "setintersectiontime:"+str(t3-t2)
    print "bruteforcetime:"+str(t4-t3)
    currentsize=currentsize*10
在最近的python版本中检查内置的“set()”数据类型——我认为它应该比列表更快。字典键过去是快速的方式,但我认为集合现在是相等的或更快的,因此如果您使用的是python的2.5之前版本,您可能会执行以下操作(不管dict中的值是什么):


最近的版本,只需将li设为set()。

为此使用
set
对象

Python2> s = set(["one", "two", "three"])
Python2> "one" in s
True

Python2> s2 = set(["three", "four", "five"])
交叉口:

Python2> s & s2
set(['three'])

Python2> x = "three"
Python2> x in s & s2
True
我想这就是你想要的,两个集合的交集。我认为,如果您了解集合对象,那么其意图也更具可读性

print set(different_values).intersection(li)
应该是一样的。。。可能会更快

>>> other_values = ["franks","pies","pie","beans"]
>>> li = ["apple","pie","franks","and","beans"]
>>> set(other_values).intersection(li)
set(['franks', 'beans', 'pie'])
以下是一些基准

In [1]: other_values = range(1000)
In [2]: li = range(500,1000)
In [3]: %timeit set(other_values).intersection(li)
10000 loops, best of 3: 78.6 us per loop
In [4]: %timeit [x for x in other_values if x in li]
100 loops, best of 3: 8.7 ms per loop
In [5]: %timeit set(other_values) & set(li)
10000 loops, best of 3: 97.6 us per loop

看起来集合交集要快得多

这实际上是
O(n^2)
,其中
li
是一个列表/序列。根据操作的不同——事实上,
n
的大小(对于3来说,这并没有什么大的区别)——可能会有一些具有更好边界的方法。根据您想做什么,您可能需要查看python
集。“更快”是什么意思?
any(x在y中表示x在不同的x中表示y在li中表示y)
@specialscope它使用哈希表,因此比大型集合列表的线性搜索更快。有趣的是,我发现了相反的情况。您将两个项都转换为set。。。有了交集,论点只需要是一个可引用的。。。使用
&
它们都需要是集合,我相信第二次转换会产生不同…你可以发布如何使用列表实现这一点的代码吗?因为我的列表不起作用。哦,我现在明白了,但你仍然需要将第一个转换为集合。交集方法可以接受任何iterable作为参数。。。它们不要求两个元素都是集合
In [1]: other_values = range(1000)
In [2]: li = range(500,1000)
In [3]: %timeit set(other_values).intersection(li)
10000 loops, best of 3: 78.6 us per loop
In [4]: %timeit [x for x in other_values if x in li]
100 loops, best of 3: 8.7 ms per loop
In [5]: %timeit set(other_values) & set(li)
10000 loops, best of 3: 97.6 us per loop