Python集查找效率

Python集查找效率,python,list,set,big-o,Python,List,Set,Big O,我知道python集合有O(1)个查找时间,python列表有O(n)个查找时间,但我对容器大小感到好奇,在这个容器大小下,将列表转换为集合是值得的 换句话说,如果我打电话给以下人员: arr = [1, 2, 3] for i in range(1000000): random.randint(1,3) in arr 这会比打电话给下面的人更有效吗 s = set([1, 2, 3]) for i in range(1000000): random.randint(1,3)

我知道python集合有O(1)个查找时间,python列表有O(n)个查找时间,但我对容器大小感到好奇,在这个容器大小下,将列表转换为集合是值得的

换句话说,如果我打电话给以下人员:

arr = [1, 2, 3]
for i in range(1000000):
    random.randint(1,3) in arr
这会比打电话给下面的人更有效吗

s = set([1, 2, 3])
for i in range(1000000):
    random.randint(1,3) in s
更重要的是,交叉长度是多少


编辑:大家一致认为,这完全取决于用户定义对象的哈希方法的效率,但对于字符串、int等原语,截止值约为1-3。

以下是一些代码,您可以使用这些代码自己测试:

您应该在您真正关心的平台和Python实现上运行它

还要注意,我搜索的是
None
,而不是
1
,因为搜索一个保证是列表中第一(或第二)项的值是常数时间,并且我使用的是与初始测试相同的整数(当然,这对于散列来说是微不足道的)。您应该根据您关心的实际数据进行测试

无论如何,在我手头的所有实现上测试它,我得到了0(64位PyPy2.1.0/2.7.3)到3(32位PyPy1.9.0/2.7.2)的截止值,其中大多数是1-2。例如,下面是64位Python 3.3.2在1:

0 0.10865500289946795 0.11782343708910048
1 0.1330389219801873 0.11656044493429363

当然,如果您有意创建一个散列速度慢且不缓存的对象,您可以将该截止值推高到您想要的高度。例如,在我的
\uuuuuu散列法中放入
time.sleep(1)
,它最终大约为12M。

您可以尝试使用
timeit
测试它。)对于不同的Python实现、平台等,交叉点会有所不同。因此,显然,您需要自己进行测试。它还取决于列表/集中的对象。对象可以定义其散列的计算方式,因此某些对象的散列速度可能比其他对象快。我觉得数据结构的选择应该是显而易见的,并且取决于您的用法/算法。@阿巴内特:这也是正确的,因此它还取决于您对相同对象与新对象进行散列的频率。正如所有这些评论所显示的,这个问题没有简单的答案:-)这对
列表
s有点不公平-它必须扫描每个元素,然后才能知道
不存在。如果在用例中,搜索到的东西通常是存在的,那么对列表进行洗牌或者查找范围的中间值(即:平均需要扫描列表的一半)会更公平。在我的设置中,交叉点大约在7000处。@drevicko:列表是线性的这一事实是我们演示的重点,所以演示这一点并不不公平。把值在中间找到而不是结束(或者根本没有)只会产生2X的差异;也许在一盘比赛之前的截止时间是2-3而不是1-2,但是谁在乎呢?哎呀!我的错!我一定是在比较μs和ns!我觉得很奇怪。
0 0.10865500289946795 0.11782343708910048
1 0.1330389219801873 0.11656044493429363