在Python中,哪种数据结构更高效/快速?假设顺序对我来说不重要,无论如何我都会检查重复,Python集比Python列表慢吗?
当前回答
与@Ellis Percival的测试相同,我想添加的是,在添加元素时,列表以类似于集合的方式执行。
添加元素
>>> def add_test_set(iterable):
... for i in range(10000):
... iterable.add(i)
...
>>> def add_test_list(iterable):
... for i in range(10000):
... iterable.append(i)
...
>>> timeit("add_test_set(iterable)",
... setup="from __main__ import add_test_set; iterable = set()",
... number=10000)
7.073143866999999
>>> timeit("add_test_list(iterable)",
... setup="from __main__ import add_test_list; iterable = list()",
... number=10000)
6.80650725000001
(我本来想编辑他的帖子,但编辑队列已经满了)
其他回答
from datetime import datetime
listA = range(10000000)
setA = set(listA)
tupA = tuple(listA)
#Source Code
def calc(data, type):
start = datetime.now()
if data in type:
print ""
end = datetime.now()
print end-start
calc(9999, listA)
calc(9999, tupA)
calc(9999, setA)
比较所有3个迭代10次后的输出: 比较
这取决于你打算用它做什么。
当涉及到确定一个对象是否存在于set中时(如x在s中),set的速度要快得多,但它的元素是没有顺序的,因此您不能像在列表中那样通过索引访问项目。在实践中,迭代集的速度也比较慢。
您可以使用timeit模块查看哪种方法更适合您的情况。
我感兴趣的结果时,检查与CPython,如果一个值是一个少量文字。set在python3中胜过tuple, list和or:
from timeit import timeit
def in_test1():
for i in range(1000):
if i in (314, 628):
pass
def in_test2():
for i in range(1000):
if i in [314, 628]:
pass
def in_test3():
for i in range(1000):
if i in {314, 628}:
pass
def in_test4():
for i in range(1000):
if i == 314 or i == 628:
pass
print("tuple")
print(timeit("in_test1()", setup="from __main__ import in_test1", number=100000))
print("list")
print(timeit("in_test2()", setup="from __main__ import in_test2", number=100000))
print("set")
print(timeit("in_test3()", setup="from __main__ import in_test3", number=100000))
print("or")
print(timeit("in_test4()", setup="from __main__ import in_test4", number=100000))
输出:
tuple
4.735646052286029
list
4.7308746771886945
set
3.5755991376936436
or
4.687681658193469
对于3到5个字面量,set仍然以较大的优势胜出,并且or成为最慢的。
在Python 2中,set总是最慢的。Or是2到3个字面量时最快的,tuple和list是4个或更多字面量时更快的。我无法区分元组和列表的速度。
当要测试的值缓存在函数外的全局变量中,而不是在循环中创建文字时,set每次都胜出,即使在python2中也是如此。
这些结果适用于Core i7上的64位CPython。
当您只想遍历值时,列表比集合略快。
但是,如果您想检查一个项是否包含在集合中,那么集合要比列表快得多。但是它们只能包含独特的项目。
事实证明,元组的执行方式几乎与列表完全相同,除了它们的不可变性。
迭代
>>> def iter_test(iterable):
... for i in iterable:
... pass
...
>>> from timeit import timeit
>>> timeit(
... "iter_test(iterable)",
... setup="from __main__ import iter_test; iterable = set(range(10000))",
... number=100000)
12.666952133178711
>>> timeit(
... "iter_test(iterable)",
... setup="from __main__ import iter_test; iterable = list(range(10000))",
... number=100000)
9.917098999023438
>>> timeit(
... "iter_test(iterable)",
... setup="from __main__ import iter_test; iterable = tuple(range(10000))",
... number=100000)
9.865639209747314
确定是否存在一个对象
>>> def in_test(iterable):
... for i in range(1000):
... if i in iterable:
... pass
...
>>> from timeit import timeit
>>> timeit(
... "in_test(iterable)",
... setup="from __main__ import in_test; iterable = set(range(1000))",
... number=10000)
0.5591847896575928
>>> timeit(
... "in_test(iterable)",
... setup="from __main__ import in_test; iterable = list(range(1000))",
... number=10000)
50.18339991569519
>>> timeit(
... "in_test(iterable)",
... setup="from __main__ import in_test; iterable = tuple(range(1000))",
... number=10000)
51.597304821014404
设置因近即时“包含”检查而获胜:https://en.wikipedia.org/wiki/Hash_table
列表实现:通常是一个数组,低层接近金属,适合迭代和随机访问的元素索引。
Set implementation: https://en.wikipedia.org/wiki/Hash_table, it does not iterate on a list, but finds the element by computing a hash from the key, so it depends on the nature of the key elements and the hash function. Similar to what is used for dict. I suspect list could be faster if you have very few elements (< 5), the larger element count the better the set will perform for a contains check. It is also fast for element addition and removal. Also always keep in mind that building a set has a cost !
注意:如果列表已经排序,那么在小列表上搜索列表可能会非常快,但是对于更多的数据集,对于包含检查会更快。
推荐文章
- 如何在交互式Python中查看整个命令历史?
- 如何显示有两个小数点后的浮点数?
- 如何有效地从数组列表或字符串数组中删除所有空元素?
- 如何用OpenCV2.0和Python2.6调整图像大小
- 在每个列表元素上调用int()函数?
- 将Set<T>转换为List<T>的最简洁的方法
- 当使用代码存储库时,如何引用资源的相对路径
- 在SQL Server上使用varchar(MAX) vs TEXT
- .toArray(new MyClass[0]) or .toArray(new MyClass[myList.size()])?
- 如何在Flask-SQLAlchemy中按id删除记录
- 在Python中插入列表的第一个位置
- 在javascript中从平面数组构建树数组
- Python Pandas只合并某些列
- 如何在一行中连接两个集而不使用“|”
- 从字符串中移除前缀