在python中,它更快 a)从n个项目列表中构建一个集合 b)将n个项目插入一组?
我找到了这个页面(http://wiki.python.org/moin/TimeComplexity),但它没有足够的信息来推断哪个更快。
看来,一次插入一个项目可能在最坏的情况下需要O(n * n)时间(假设它使用dicts),并且在一般情况下需要O(n * 1)。初始化带有列表的集合是否可以提高性能?
答案 0 :(得分:19)
就O()
复杂性而言 - 它肯定是相同的,因为两种方法完全相同 - 将n
项插入集合中。
差异来自实现:从iterable初始化的一个明显优势是你可以保存很多Python级函数调用 - 迭代的初始化完全在C级(**)完成。
实际上,对5,000,000个随机整数列表的一些测试表明,逐个添加的速度较慢:
lst = [random.random() for i in xrange(5000000)]
set1 = set(lst) # takes 2.4 seconds
set2 = set() # takes 3.37 seconds
for item in lst:
set2.add(item)
(**)查看集合代码(Objects/setobject.c
),最终项目插入归结为对set_add_key
的调用。从iterable初始化时,在紧C循环中调用此函数:
while ((key = PyIter_Next(it)) != NULL) {
if (set_add_key(so, key) == -1) {
Py_DECREF(it);
Py_DECREF(key);
return -1;
}
Py_DECREF(key);
}
另一方面,每次调用set.add
都会调用属性查找,该属性查找解析为C set_add
函数,后者又调用set_add_key
。由于项目添加本身相对较快(Python的哈希表实现非常高效),所以这些额外的调用都会建立起来。
答案 1 :(得分:2)
$ python -V
Python 2.5.2
$ python -m timeit -s "l = range(1000)" "set(l)"
10000 loops, best of 3: 64.6 usec per loop
$ python -m timeit -s "l = range(1000)" "s = set()" "for i in l:s.add(i)"
1000 loops, best of 3: 307 usec per loop
答案 2 :(得分:0)
以下是使用timeit
运行比较的结果。似乎使用list的set初始化更快,很想知道为什么会这样:
from timeit import timeit
timeit("set(a)","a=range(10)")
# 0.9944498532640864
timeit("for i in a:x.add(i)","a=range(10);x=set()")
# 1.6878826778265648
Python版本:2.7
答案 3 :(得分:0)
在我的Thinkpad上:
In [37]: timeit.timeit('for a in x: y.add(a)',
'y=set(); x=range(10000)', number=10000)
Out[37]: 12.18006706237793
In [38]: timeit.timeit('y=set(x)', 'y=set(); x=range(10000)', number=10000)
Out[38]: 3.8137960433959961