Python 哪个更快?为什么?集合还是列表?

Python 哪个更快?为什么?集合还是列表?,python,list,graph,set,Python,List,Graph,Set,假设我有一个图,想看看N[a]中的b。哪种实现更快?为什么 a, b = range(2) N = [set([b]), set([a,b])] 或 这显然过于简单了,但想象一下,图形变得非常密集。在一个集合中进行成员资格测试要快得多,特别是对于大型集合。这是因为集合使用映射到bucket。由于Python实现会自动调整该哈希表的大小,因此无论集合大小如何(假设哈希函数足够好),速度都可以保持不变() 相反,为了评估一个对象是否是列表的成员,Python必须比较每个成员是否相等,即测试是O(n

假设我有一个图,想看看N[a]中的
b。哪种实现更快?为什么

a, b = range(2)
N = [set([b]), set([a,b])]


这显然过于简单了,但想象一下,图形变得非常密集。

在一个集合中进行成员资格测试要快得多,特别是对于大型集合。这是因为集合使用映射到bucket。由于Python实现会自动调整该哈希表的大小,因此无论集合大小如何(假设哈希函数足够好),速度都可以保持不变()


相反,为了评估一个对象是否是列表的成员,Python必须比较每个成员是否相等,即测试是
O(n)

集(我的意思是像HashSet这样基于散列的集)比列表查找值快得多。列表必须按顺序进行,以确定该值是否存在。HashSet可以直接跳转并定位bucket,几乎在一个固定的时间内查找一个值

这完全取决于你想要完成什么。使用您的示例逐字记录,使用列表会更快,因为您不必经历创建集合的开销:

import timeit

def use_sets(a, b):
    return [set([b]), set([a, b])]

def use_lists(a, b):
    return [[b], [a, b]]

t=timeit.Timer("use_sets(a, b)", """from __main__ import use_sets
a, b = range(2)""")
print "use_sets()", t.timeit(number=1000000)

t=timeit.Timer("use_lists(a, b)", """from __main__ import use_lists
a, b = range(2)""")
print "use_lists()", t.timeit(number=1000000)
产生:

use_sets() 1.57522511482
use_lists() 0.783344984055
但是,由于前面提到的原因,在搜索大型集合时使用集合会使您受益匪浅。通过你的例子,你不可能知道拐点在哪里,你是否会看到好处


我建议您对它进行双向测试,并针对您的特定用例使用更快的方法。

请告诉我。还值得指出的是,OP在第一个示例中有一个列表列表,在第二个示例中有一个集合列表。因为在这两种情况下,外部容器都是一个列表,所以在这两种情况下,搜索都是O(n)。Python集是动态调整大小的哈希表,所以不管项目的数量如何,都会得到O(1)的摊销@g、 d.d.c OP询问关于容器列表中单个项目(
b in N[a]
)的成员资格测试,即
N
,因此不,这两种情况都不是O(N)。@delnan你是对的,
O(1)
(+notes)是比
O(logn)
(-notes)更好的描述。@phihag O(1)不仅仅比O(logn)好:O(1)正确,O(logn)不是。@NedBatchelder:事实上,如果你查阅数学定义,你会发现O(logn)是正确的,只要O(1)是常数,它也有logn的边界。所以O(1)比O(logn)更好。
use_sets() 1.57522511482
use_lists() 0.783344984055