Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/298.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jsf-2/2.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_Arrays_Performance_Sorting - Fatal编程技术网

用Python进行排序的最快方法

用Python进行排序的最快方法,python,arrays,performance,sorting,Python,Arrays,Performance,Sorting,在Python中,对大于0小于100000的整数数组进行排序的最快方法是什么?但不使用诸如sort之类的内置函数 我正在考虑根据输入大小组合两个运动功能的可能性。因为您知道数字的范围,所以可以使用时间上是线性的。内置功能是最好的,但是因为您不能使用它们,请看一下: 如果您对渐近时间感兴趣,那么计数排序或基数排序可以提供良好的性能 但是,如果您对挂钟时间感兴趣,则需要使用特定数据集比较不同算法之间的性能,因为不同算法对不同数据集的性能不同。在这种情况下,尝试快速排序总是值得的: def qsort

在Python中,对大于0小于100000的整数数组进行排序的最快方法是什么?但不使用诸如sort之类的内置函数


我正在考虑根据输入大小组合两个运动功能的可能性。

因为您知道数字的范围,所以可以使用时间上是线性的。

内置功能是最好的,但是因为您不能使用它们,请看一下:


如果您对渐近时间感兴趣,那么计数排序或基数排序可以提供良好的性能

但是,如果您对挂钟时间感兴趣,则需要使用特定数据集比较不同算法之间的性能,因为不同算法对不同数据集的性能不同。在这种情况下,尝试快速排序总是值得的:

def qsort(inlist):
    if inlist == []: 
        return []
    else:
        pivot = inlist[0]
        lesser = qsort([x for x in inlist[1:] if x < pivot])
        greater = qsort([x for x in inlist[1:] if x >= pivot])
        return lesser + [pivot] + greater
def qsort(内部列表):
如果inlist=[]:
返回[]
其他:
pivot=inlist[0]
lesser=qsort([x代表inlist[1:]中的x,如果x=pivot])
返回较小值+[枢轴]+较大值

来源:

早期版本的Python使用了
samplesort
(大样本快速排序的变体)和二进制插入排序的混合作为内置排序算法。这证明有点不稳定。S0,从python 2.3开始使用
自适应合并排序
算法

合并排序顺序(平均)=
O(nlogn)
。 合并排序顺序(最差)=
O(nlogn)
。 但快速排序顺序(最差)=n*2

如果您使用
list=[………]

list.sort()
使用
mergesort算法。

对于排序算法之间的比较,您可以阅读


对于细节比较

我们可以使用字典进行计数排序,以最大限度地减少额外的空间使用,并保持较低的运行时间。对于小尺寸的输入数组,计数排序要慢得多,这是因为python与C实现开销的关系。当数组(count)的大小约为100万时,count排序开始超过常规排序

如果您真的想为较小的输入带来巨大的加速,那么可以在C中实现计数排序,并从Python中调用它

(修复了Aaron(+1)帮助捕获的错误…) 下面的纯python实现比较了这两种方法

import random
import time

COUNT = 3000000

array = [random.randint(1,100000) for i in range(COUNT)]
random.shuffle(array)

array1 = array[:]

start = time.time()
array1.sort()
end = time.time()
time1 = (end-start)
print 'Time to sort = ', time1*1000, 'ms'

array2 = array[:]

start = time.time()
ardict = {}
for a in array2:
    try:
        ardict[a] += 1
    except:
        ardict[a] = 1

indx = 0
for a in sorted(ardict.keys()):
    b = ardict[a]
    array2[indx:indx+b] = [a for i in xrange(b)]
    indx += b

end = time.time()
time2 = (end-start)
print 'Time to count sort = ', time2*1000, 'ms'

print 'Ratio =', time2/time1

基数排序理论上是以线性时间运行的(排序时间大致与数组大小成正比),但在实践中,快速排序可能更适合,除非您对绝对庞大的数组进行排序

如果要使快速排序更快一些,可以在数组大小变小时使用插入排序]

理解算法复杂性和大O表示法的概念可能也会有所帮助。

def sort(l):
def sort(l):
    p = 0
    while(p<len(l)-1):
        if(l[p]>l[p+1]):
            l[p],l[p+1] = l[p+1],l[p]
            if(not(p==0)):
                p = p-1
        else:
            p += 1
    return l
p=0 而(pl[p+1]): l[p],l[p+1]=l[p+1],l[p] 如果(不是(p==0)): p=p-1 其他: p+=1 返回l
这是我创建的一个算法,但速度非常快。只需排序(l) l是要排序的列表。

@fmark 我在上一篇文章中针对python快速排序编写了python合并排序实现的一些基准测试 从上面回答

  • 列表的大小和列表中数字的大小无关
  • 合并排序获胜,但它使用内置int()进行排序

    将numpy导入为np
    x=列表(np.random.rand(100))
    #测试1,合并\排序
    def合并(l、p、q、r):
    n1=q-p+1
    n2=r-q
    左=l[p:p+n1]
    右=l[q+1:q+1+n2]
    i=0
    j=0
    k=p
    当k
    我可能会迟到一点,但是有一篇有趣的文章比较了不同的种类

    一个主要的收获是,虽然默认排序做得很好,但我们可以使用编译版的quicksort做得更好。这需要Numba包

    以下是Github回购协议的链接:

    为什么不使用内置功能?在路上最快的方式是什么,但不驾驶保时捷?安德斯:不要重新发明车轮。内置的sort()应该足以满足您的情况。我很好奇:为什么需要实现自己的排序例程?对我来说,这闻起来像是一个家庭作业:-)@Aaron-或者更确切地说-不使用任何类型的预制车辆,在路上走最快的路是什么;)timsort比mergesortTimsort更具适应性。timsort是一种自适应、稳定、自然的mergesort。除了选择变量列表外,还有一些好的建议,这可能会导致很好的错误。我发布了另一个更快的版本。在同一组变量上运行两次列表理解可能也不太理想。@Tony Veijalainen“计算机科学中只有两件困难的事情:缓存失效和命名”——我更改了变量名(我没有否决)。请注意,如果整数数组明显小于100000,则这不是一个好的算法,因为在我的机器上构建100000元素列表将浪费内存(从而浪费时间)。+1
    Ratio=1.16710428623
    。巧妙地使用了口述。尽管如此,值得注意的是
    import numpy as np
    x = list(np.random.rand(100))
    
    
    # TEST 1, merge_sort 
    def merge(l, p, q, r):
        n1 = q - p + 1
        n2 = r - q
        left = l[p : p + n1]
        right = l[q + 1 : q + 1 + n2]
    
        i = 0
        j = 0
        k = p
        while k < r + 1:
            if i == n1:
                l[k] = right[j]
                j += 1
            elif j == n2:
                l[k] = left[i]
                i += 1
            elif  left[i] <= right[j]:
                l[k] = left[i]
                i += 1
            else:
                l[k] = right[j]
                j += 1
            k += 1
    
    def _merge_sort(l, p, r):
        if p < r:
            q = int((p + r)/2)
            _merge_sort(l, p, q)
            _merge_sort(l, q+1, r)
            merge(l, p, q, r)
    
    def merge_sort(l):
        _merge_sort(l, 0, len(l)-1)
    
    # TEST 2
    def quicksort(array):
        _quicksort(array, 0, len(array) - 1)
    
    def _quicksort(array, start, stop):
        if stop - start > 0:
            pivot, left, right = array[start], start, stop
            while left <= right:
                while array[left] < pivot:
                    left += 1
                while array[right] > pivot:
                    right -= 1
                if left <= right:
                    array[left], array[right] = array[right], array[left]
                    left += 1
                    right -= 1
            _quicksort(array, start, right)
            _quicksort(array, left, stop)
    
    # TEST 3
    def qsort(inlist):
        if inlist == []: 
            return []
        else:
            pivot = inlist[0]
            lesser = qsort([x for x in inlist[1:] if x < pivot])
            greater = qsort([x for x in inlist[1:] if x >= pivot])
            return lesser + [pivot] + greater
    
    def test1():
        merge_sort(x)
    
    def test2():
        quicksort(x)
    
    def test3():
        qsort(x)
    
    if __name__ == '__main__':
        import timeit
        print('merge_sort:', timeit.timeit("test1()", setup="from __main__ import test1, x;", number=10000))
        print('quicksort:', timeit.timeit("test2()", setup="from __main__ import test2, x;", number=10000))
        print('qsort:', timeit.timeit("test3()", setup="from __main__ import test3, x;", number=10000))