【发布时间】:2011-12-04 17:52:44
【问题描述】:
假设我有一个图表,想看看b in N[a]。哪个实现更快?为什么?
a, b = range(2)
N = [set([b]), set([a,b])]
或
N= [[b],[a,b]]
这显然过于简单了,但想象一下图变得非常密集。
【问题讨论】:
假设我有一个图表,想看看b in N[a]。哪个实现更快?为什么?
a, b = range(2)
N = [set([b]), set([a,b])]
或
N= [[b],[a,b]]
这显然过于简单了,但想象一下图变得非常密集。
【问题讨论】:
集合中的成员资格测试要快得多,尤其是对于大型集合。这是因为该集合使用hash function 映射到存储桶。由于 Python 实现会自动调整该哈希表的大小,因此无论集合大小如何(假设哈希函数足够好),速度都可以保持恒定 (O(1))。
相比之下,要评估一个对象是否是列表的成员,Python 必须比较每个成员的相等性,即测试是 O(n)。
【讨论】:
N 容器列表中单个项目 (b in N[a]) 的成员资格测试,所以不,它不是O(n)。
O(1) (+notes) 比 O(log n) (-notes) 更好。
这完全取决于您要完成的工作。逐字使用您的示例,使用列表会更快,因为您不必经历创建集合的开销:
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
但是,由于这里已经提到的原因,当您搜索大型集合时,您会受益于使用集合。通过您的示例无法判断拐点对您来说在哪里以及您是否会看到好处。
我建议您对这两种方式都进行测试,并为您的特定用例选择更快的方法。
【讨论】:
Set(我的意思是像 HashSet 这样的基于散列的集合)比 List 查找值要快得多。 List 必须按顺序查找该值是否存在。 HashSet 几乎可以在恒定时间内直接跳转定位桶查找值。
【讨论】: