`sorted(list)`和`list.sort()`有什么区别? python

list.sort()对列表进行sorting并保存已sorting的列表,而sorted(list)返回已sorting的列表而不更改原始列表。

  • 但是什么时候用哪个?
  • 哪个更快? 还有多快?
  • 列表的原始位置可以检索list.sort()

sorted()返回一个新的sorting列表,保持原始列表不受影响。 list.sort() 就地对列表进行sorting,改变列表的索引,并返回None (就像所有就地操作一样)。

sorted()适用于任何可迭代的,而不仅仅是列表。 string,元组,字典(你会得到键),生成器等,返回一个包含所有元素的列表,sorting。

  • 当你想改变列表的时候使用list.sort() ,当你想要一个新的sorting的对象时,使用sorted() 。 使用sorted()当你想sorting的东西是一个可迭代的,而不是一个列表

  • 对于列表, list.sort()sorted()更快,因为它不需要创build副本。 对于任何其他迭代,你别无select。

  • 不,你不能找回原来的位置。 一旦你调用list.sort() ,原来的顺序就没有了。

sorted(list) vs list.sort()什么list.sort()

  • list.sort列表并返回None
  • sorted创build一个新的列表从旧&返回新的,sorting。

sorted等同于这个Python实现,但CPython内置函数应该运行得更快,因为它是用C写成的:

 def sorted(original_list): list_copy = list(original_list) # make a copy list_copy.sort() # sort it return list_copy # return the copied and sorted list 

(要复制,我们可以使用一个分片,或者在Python 3中使用list.copy,但是对于我们的目的来说, list已经足够清晰了。)

什么时候用哪个?

  • 当你不希望保留原来的sorting顺序时,使用list.sort (因此,你将能够在内存中就地重用列表),当你是列表的唯一所有者时(如果列表被其他人共享代码和你改变它,你可以引入错误的地方使用该列表。)
  • 如果要保留原始sorting顺序,或者希望创build只有本地代码拥有的新列表,请使用sorted顺序。

列表的原始位置可以检索list.sort()之后?

不可以 – 除非你自己做了一个副本,否则这些信息就会丢失,因为sorting是在原地完成的。

“哪个更快?还有多快?”

为了说明创build新列表的惩罚,使用timeit模块,这里是我们的设置:

 import timeit setup = """ import random lists = [list(range(10000)) for _ in range(1000)] # list of lists for l in lists: random.shuffle(l) # shuffle each list shuffled_iter = iter(lists) # wrap as iterator so next() yields one at a time """ 

这里是我们对随机排列的10000个整数列表的结果,正如我们在这里可以看到的,我们已经反证了一个较早的列表创build费用的误区 :

Python 2.7

 >>> timeit.repeat("next(shuffled_iter).sort()", setup=setup, number = 1000) [3.75168503401801, 3.7473005310166627, 3.753129180986434] >>> timeit.repeat("sorted(next(shuffled_iter))", setup=setup, number = 1000) [3.702025591977872, 3.709248117986135, 3.71071034099441] 

Python 3

 >>> timeit.repeat("next(shuffled_iter).sort()", setup=setup, number = 1000) [2.797430992126465, 2.796825885772705, 2.7744789123535156] >>> timeit.repeat("sorted(next(shuffled_iter))", setup=setup, number = 1000) [2.675589084625244, 2.8019039630889893, 2.849375009536743] 

经过一些反馈,我决定另一个testing将是可取的,具有不同的特点。 在这里,我提供了每次迭代1,000次的相同的随机sorting的100,000个列表。

 import timeit setup = """ import random random.seed(0) lst = list(range(100000)) random.shuffle(lst) """ 

我解释了Martijn提到的复制所带来的这种更大的差异,但是它并不支配这里较为stream行的答案中提到的观点,这里时间的增加只有大约10%

 >>> timeit.repeat("lst[:].sort()", setup=setup, number = 10000) [572.919036605, 573.1384446719999, 568.5923951] >>> timeit.repeat("sorted(lst[:])", setup=setup, number = 10000) [647.0584738299999, 653.4040515829997, 657.9457361929999] 

我也跑了上面的一个小得多的sorting,并看到新的sorted复制版本仍然需要大约2个百分点的长度上运行时间的2%。

Poke也运行了自己的代码,代码如下:

 setup = ''' import random random.seed(12122353453462456) lst = list(range({length})) random.shuffle(lst) lists = [lst[:] for _ in range({repeats})] it = iter(lists) ''' t1 = 'l = next(it); l.sort()' t2 = 'l = next(it); sorted(l)' length = 10 ** 7 repeats = 10 ** 2 print(length, repeats) for t in t1, t2: print(t) print(timeit(t, setup=setup.format(length=length, repeats=repeats), number=repeats)) 

他find了100万长的sorting,(跑了100多次)类似的结果,但只有大约5%的时间增加,这里的输出:

 10000000 100 l = next(it); l.sort() 610.5015971539542 l = next(it); sorted(l) 646.7786222379655 

结论:

一个大型的列表被sorting并创build一个副本可能会主导差异,但sorting本身主宰着操作,围绕这些差异组织代码将是过早的优化。 当我需要一个新的数据sorting列表时,我会使用sorted当我需要list.sortsorting列表时,我会使用list.sort ,并让它决定我的用法。

主要区别是sorted(some_list)返回一个新的list

 a = [3, 2, 1] print sorted(a) # new list print a # is not modified 

some_list.sort()对列表进行sorting

 a = [3, 2, 1] print a.sort() # in place print a # it's modified 

请注意 ,因为a.sort()不返回任何内容,所以print a.sort()将会打印None


list.sort()之后可以检索列表的原始位置吗?

不,因为它修改了原始列表。