`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)
vslist.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.sort
sorting列表时,我会使用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()之后可以检索列表的原始位置吗?
不,因为它修改了原始列表。