Python 列表列表与元组集合的时间复杂度

Python 列表列表与元组集合的时间复杂度,python,list,set,big-o,hashtable,Python,List,Set,Big O,Hashtable,我经常读到集合操作是O(1),最坏的情况是O(N),而检查列表成员是O(N)。因此,当一位朋友在添加列表之前检查列表是否在列表中时,我建议改为使用一组元组。然而,在计时时,列表的速度更快!为什么会这样?向集合中添加元组如何比遍历列表列表慢 下面是一些示例测试代码 import time a = [] b = [] for i in range(10000): a.append(list(range(100))) b.append(tuple(range(100)))

我经常读到集合操作是O(1),最坏的情况是O(N),而检查列表成员是O(N)。因此,当一位朋友在添加列表之前检查列表是否在列表中时,我建议改为使用一组元组。然而,在计时时,列表的速度更快!为什么会这样?向集合中添加元组如何比遍历列表列表慢

下面是一些示例测试代码

import time
a = []
b = []

for i in range(10000):
    a.append(list(range(100)))
    b.append(tuple(range(100)))
    


p=[]
tic=time.perf_counter()
for i in range(100):
    if a[i] not in p:
        p.append(a[i])
toc=time.perf_counter()
print(toc-tic)  # Was about 100ms

q=set()
tic=time.perf_counter()
for i in range(100):
    q.add(b[i])
toc=time.perf_counter()
print(toc-tic)  # Was about 169ms

r=dict()
tic=time.perf_counter()
for i in range(100):
    r[b[i]]=None
toc=time.perf_counter()
print(toc-tic)  # Was about 143ms

您没有很好地测试哪一个更快,因为您只是在
p,q,r
中添加了一个元素,因为
a
仅由一个重复的元素组成:list(范围(100)),而
b
也是如此

一个更好的测试是这个修改版本,您将看到您期望的结果,因为在这里您将向
A
b
添加不同的元素:

import time
a = []
b = []

for i in range(100000):
    a.append(i)
    b.append(i)
           
p=[]
tic=time.perf_counter()
for i in range(100):
    if a[i] not in p:
        p.append(a[i])
toc=time.perf_counter()
print(toc-tic)  

q=set()
tic=time.perf_counter()
for i in range(100):
    q.add(b[i])
toc=time.perf_counter()
print(toc-tic)  

r=dict()
tic=time.perf_counter()
for i in range(100):
    r[b[i]]=None
toc=time.perf_counter()
print(toc-tic)  

好吧,别客气。事实证明,这是由于列表的构造方式:嵌套列表不是唯一的,因此检查列表是否在列表中本质上是O(1),因为它始终是第一个列表。做了这个小小的修改,世界上的一切又恢复了正常:


a = []
b=[]
m=100
n=100
for i in range(n):
    a.append(list(range(i,i+m)))
    b.append(tuple(range(i,i+m)))
    


p=[]
tic=time.perf_counter()
for i in range(n):
    if a[i] not in p:
        p.append(a[i])
toc=time.perf_counter()
print(toc-tic)

q=set()
tic=time.perf_counter()
for i in range(n):
    q.add(b[i])
toc=time.perf_counter()
print(toc-tic) 

r=dict()
tic=time.perf_counter()
for i in range(n):
    r[b[i]]=None
toc=time.perf_counter()
print(toc-tic) 

谢谢尽管问题是关于元组与列表的,而不仅仅是整数值。但是,我可以将列表创建修改为
list(range(I,m+I))
,这样每个列表都是唯一的,而且集合/字典的时间安排确实比列表搜索更好。是的,但最终拥有列表或整数并不重要,重要的是拥有唯一的元素