Python中列表函数的代价
基于,Python中列表函数的成本似乎是:Python中列表函数的代价,python,performance,list,Python,Performance,List,基于,Python中列表函数的成本似乎是: 随机存取:O(1) 正面插入/删除:O(n) 背面插入/删除:O(1) 有人能确认这在Python2.6/3.x中是否仍然正确吗?没错,在前面插入将强制移动所有元素 collections.deque提供了类似的功能,但针对两侧的插入进行了优化。看一看。这是另一种名单的动员。指定的版本为2.6/3.0 追加(插入到后面)是O(1),而插入(其他地方)是O(n)。所以是的,看起来这仍然是事实 Operation...Complexity Copy..
- 随机存取:O(1)
- 正面插入/删除:O(n)
- 背面插入/删除:O(1)
有人能确认这在Python2.6/3.x中是否仍然正确吗?没错,在前面插入将强制移动所有元素
collections.deque提供了类似的功能,但针对两侧的插入进行了优化。看一看。这是另一种名单的动员。指定的版本为2.6/3.0
追加(插入到后面)是O(1)
,而插入(其他地方)是O(n)
。所以是的,看起来这仍然是事实
Operation...Complexity
Copy........O(n)
Append......O(1)
Insert......O(n)
Get Item....O(1)
Set Item....O(1)
Del Item....O(n)
Iteration...O(n)
Get Slice...O(k)
Del Slice...O(n)
Set Slice...O(n+k)
Extend......O(k)
Sort........O(n log n)
Multiply....O(nk)
Python3主要是一种进化变化,数据结构及其复杂性没有大的变化
Python集合的规范源代码在Wiki上。Fwiw,如果需要,有一个更快的(对于某些操作…insert是O(logn))名为BList 我知道这篇文章很老,但我最近自己做了一个小测试。list.insert()的复杂性似乎是O(n)
代码:
“”
独立学习,python中的定时插入列表方法
'''
导入时间
def制作列表大小(n):
ret_list=[]
对于范围(n)中的i:
ret_list.append(n)
返回重新列表
#定时环路的估计开销
def get_开销(硝酸盐):
'''
返回迭代for循环所需的时间
'''
tic=time.time()
对于范围内的i(硝酸盐):
通过#只是盲目地重复,一次又一次
toc=时间。时间()
间接费用=总成本
返回开销
def tictoc_中点_插入(列表大小_首字母、列表大小_末字母、字母、文件):
开销=获取开销(niters)
列表大小=列表大小初始值
#插入_pt=list_size//2#谢谢Ryeguy谢谢。同样来自kaizer.se引用的时间复杂性文档:s中的x。。。。。。。。。。。O(n)最小值(s)、最大值(x)。。。O(n)@ryeguy:惊讶地发现插入和删除都是O(n)操作。列表数据结构的全部目的不是将插入和删除的时间复杂度降低到O(1)吗?从上面看,底层数据结构更像是一个数组。我错过了什么吗?@AKE-see。在数据结构的不同实现中存在权衡。在您典型的O(1)插入/删除列表中,您经常将项目作为O(n)获取。@MikeS:是的,我明白了。在提出这个问题之后,我发现处理器体系结构也使实际实现的选择有所不同。例如,具有缓存行为的处理器,其中每次内存访问都会拉回具有相邻内存的缓存线,这意味着实际上,从缓存中保存的相邻内存地址进行O(n)插入/删除实际上比O(1)更快从内存中随机分布的位置访问内存。检查数字列表中是否存在整数的复杂性是多少?>>3在Lisa中,这是否意味着底层数据结构是一个数组?如果它是一个列表,任何地方的插入,包括前面的插入,都应该是一个O(1)操作,对吗?
'''
Independent Study, Timing insertion list method in python
'''
import time
def make_list_of_size(n):
ret_list = []
for i in range(n):
ret_list.append(n)
return ret_list
#Estimate overhead of timing loop
def get_overhead(niters):
'''
Returns the time it takes to iterate a for loop niter times
'''
tic = time.time()
for i in range(niters):
pass #Just blindly iterate, niter times
toc = time.time()
overhead = toc-tic
return overhead
def tictoc_midpoint_insertion(list_size_initial, list_size_final, niters,file):
overhead = get_overhead(niters)
list_size = list_size_initial
#insertion_pt = list_size//2 #<------- INSERTION POINT ASSIGMNET LOCATION 1
#insertion_pt = 0 #<--------------- INSERTION POINT ASSIGNMENT LOCATION 4 (insert at beginning)
delta = 100
while list_size <= list_size_final:
#insertion_pt = list_size//2 #<----------- INSERTION POINT ASSIGNMENT LOCATION 2
x = make_list_of_size(list_size)
tic = time.time()
for i in range(niters):
insertion_pt = len(x)//2 #<------------- INSERTION POINT ASSIGNMENT LOCATION 3
#insertion_pt = len(x) #<------------- INSERTION POINT ASSIGN LOC 5 insert at true end
x.insert(insertion_pt,0)
toc = time.time()
cost_per_iter = (toc-tic)/niters #overall time cost per iteration
cost_per_iter_no_overhead = (toc - tic - overhead)/niters #the fraction of time/iteration, #without overhead cost of pure iteration
print("list size = {:d}, cost without overhead = {:f} sec/iter".format(list_size,cost_per_iter_no_overhead))
file.write(str(list_size)+','+str(cost_per_iter_no_overhead)+'\n')
if list_size >= 10*delta:
delta *= 10
list_size += delta
def main():
fname = input()
file = open(fname,'w')
niters = 10000
tictoc_midpoint_insertion(100,10000000,niters,file)
file.close()
main()