为什么python需要更长的时间来排序列表副本?

时间:2016-09-19 20:31:52

标签: python performance sorting timeit

为什么在排序x和y时会有这么大的差异而y只是x的副本? python不会立即复制列表吗?

python -mtimeit -s'import random; x=range(1000); random.shuffle(x)' 'y=list(x); x.sort()'
100000 loops, best of 3: 19.5 usec per loop
python -mtimeit -s'import random; x=range(1000); random.shuffle(x)' 'y=list(x); y.sort()'
1000 loops, best of 3: 211 usec per loop
python -mtimeit -s'import random; x=range(1000); random.shuffle(x)' 'x.sort()'
100000 loops, best of 3: 15.9 usec per loop

1 个答案:

答案 0 :(得分:3)

您的第一个和最后一个示例必须对列表进行排序一次。之后,Python使用的排序算法很容易,因为它被优化以利用已排序的序列

来自Wikipedia article on TimSort(Python排序算法):

  

该算法查找已经排序的数据的子序列,并使用该知识更有效地对其余数据进行排序。

换句话说,list(y); y.sort()案例弱势因为每次都会给出一个干净,未排序的列表。 x.sort()情况给出了完全排序的列表(在第一次迭代之后)。毕竟,list.sort()到位排序,改变列表。 timeit测试不会为每个测试创建副本,因此后续测试会重复使用相同的列表。

如果您切换到使用sorted()功能,您将再也看不到时间优势了,因为sorted()会返回新的,复制并排序的列表而不是就地分类:

python -mtimeit -s'import random; x=range(1000); random.shuffle(x)' 'y=list(x); sorted(x)'
10000 loops, best of 3: 151 usec per loop
python -mtimeit -s'import random; x=range(1000); random.shuffle(x)' 'y=list(x); sorted(y)'
10000 loops, best of 3: 155 usec per loop
python -mtimeit -s'import random; x=range(1000); random.shuffle(x)' 'sorted(x)'
10000 loops, best of 3: 152 usec per loop