Python 'sorted(list)`vs'list.sort()`之间有什么区别?

Python 'sorted(list)`vs'list.sort()`之间有什么区别?,python,list,sorting,copy,in-place,Python,List,Sorting,Copy,In Place,list.sort()对列表进行排序并替换原始列表,而sorted(list)返回列表的排序副本,而不更改原始列表 什么时候一个优先于另一个 哪个更有效?多少钱 执行list.sort()后,列表能否恢复为未排序状态 主要区别在于排序(某些列表)返回新列表: a = [3, 2, 1] print sorted(a) # new list print a # is not modified a = [3, 2, 1] print a.sort() # in place pri

list.sort()
对列表进行排序并替换原始列表,而
sorted(list)
返回列表的排序副本,而不更改原始列表

  • 什么时候一个优先于另一个
  • 哪个更有效?多少钱
  • 执行
    list.sort()
    后,列表能否恢复为未排序状态

主要区别在于
排序(某些列表)
返回
列表

a = [3, 2, 1]
print sorted(a) # new list
print a         # is not modified
a = [3, 2, 1]
print a.sort() # in place
print a         # it's modified
some_list.sort()
对列表进行适当排序

a = [3, 2, 1]
print sorted(a) # new list
print a         # is not modified
a = [3, 2, 1]
print a.sort() # in place
print a         # it's modified
注意由于
a.sort()
不返回任何内容,
print a.sort()
将打印
None


能否在list.sort()之后检索列表原始位置?

否,因为它会修改原始列表。

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

sorted()。字符串、元组、字典(您将获得键)、生成器等,返回包含所有元素的列表,并进行排序

  • 当您想要改变列表时,请使用
    list.sort()
    ,当您想要返回新的排序对象时,请使用
    sorted()
    。当您想对iterable而不是list的内容进行排序时,请使用
    sorted()

  • 对于列表,
    list.sort()
    sorted()
    快,因为它不必创建副本。对于任何其他iterable,您别无选择

  • 不,您无法检索原始位置。调用
    list.sort()
    后,原始顺序将消失

sorted(list)
list.sort()之间有什么区别?
  • list.sort
    在适当的位置改变列表并返回
    None
  • sorted
    接受任何iterable并返回一个新列表,已排序
sorted
相当于这个Python实现,但是CPython内置函数应该运行得更快,因为它是用C编写的:

def sorted(iterable, key=None):
    new_list = list(iterable)    # make a new list
    new_list.sort(key=key)       # sort it
    return new_list              # return it
什么时候用哪个?
  • 如果不希望保留原始排序顺序,请使用
    list.sort
    (这样您就可以在内存中就地重用列表。)以及 您是列表的唯一所有者(如果列表由其他代码共享 如果对其进行变异,可能会在使用该列表的地方引入bug。)
  • 当您希望保留原始排序顺序或在需要时,请使用
    sorted
    希望创建一个只有本地代码拥有的新列表
能否在list.sort()之后检索列表的原始位置? 否-除非您自己制作了一份副本,否则该信息将丢失,因为排序已完成

“哪个更快?快多少?” 为了说明创建新列表的代价,请使用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个整数的结果,正如我们在这里看到的,我们已经证明:

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]

经过一些反馈后,我决定再进行一次具有不同特征的测试。在这里,我提供了相同的随机排序列表,每个迭代1000次,长度为100000

import timeit
setup = """
import random
random.seed(0)
lst = list(range(100000))
random.shuffle(lst)
"""
我认为这种更大的差异来自Martijn提到的复制,但它并没有占主导地位,在这里,时间的增长只有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]
我还以更小的排序运行了上面的内容,发现新的
排序的
拷贝版本在1000个长度的排序上仍然需要大约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))
他发现1000000长度排序(运行100次)的结果类似,但时间只增加了约5%,以下是输出:

10000000 100
l = next(it); l.sort()
610.5015971539542
l = next(it); sorted(l)
646.7786222379655
结论: 使用
sorted
排序的大型列表复制副本可能会主导差异,但排序本身主导操作,围绕这些差异组织代码将是过早的优化。当我需要一个新的数据排序列表时,我会使用
sorted
,当我需要对一个列表进行排序时,我会使用
list.sort
,并让它决定我的用法。

函数.sort()将新列表的值直接存储在list变量中;所以第三个问题的答案是否定的。 另外,如果使用sorted(list)执行此操作,则可以使用它,因为它不存储在list变量中。有时.sort()方法也充当函数,或者说它包含参数

必须将sorted(list)的值显式存储在变量中


对于短时间的数据处理,速度也没有差别;但对于长名单;您应该直接使用.sort()方法进行快速工作;但你将再次面临不可逆转的行动

这里有几个简单的例子来说明行动上的区别:

请参见此处的数字列表:

nums = [1, 9, -3, 4, 8, 5, 7, 14]
在此列表上调用
sorted
时,
sorted
将对列表进行复制。(意味着您的原始列表将保持不变。)

让我看看

sorted(nums)
返回

[-3, 1, 4, 5, 7, 8, 9, 14]
再次查看
nums

nums
我们看到原始列表(未更改且未排序)<代码>已排序
未更改原始列表

[1, 2, -3, 4, 8, 5, 7, 14]
使用相同的
nums
列表并对其应用
sort
功能,将更改实际列表

让我看看

sorted(nums)
从我们的
nums
列表开始,确保内容仍然相同

nums

[-3, 1, 4, 5, 7, 8, 9, 14]

nums.sort()
现在原始nums列表已更改,查看nums,我们看到原始列表已更改,现在已排序

nums
[-3, 1, 2, 4, 5, 7, 8, 14]