Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/287.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python中列表函数的代价_Python_Performance_List - Fatal编程技术网

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..

基于,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(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()