list.sort()对列表进行排序并替换原始列表,而sorted(list)则返回列表的排序副本,而不改变原始列表。
什么时候一个比另一个更受欢迎? 哪个更有效率?差多少? 执行list.sort()后,列表是否可以恢复到无序状态?
请使用为什么这些列表操作(方法)返回None,而不是结果列表?关闭OP无意中分配了.sort()结果的问题,而不是使用sorted或单独的语句。正确的调试将显示.sort()返回None,此时“为什么?”是剩下的问题。
list.sort()对列表进行排序并替换原始列表,而sorted(list)则返回列表的排序副本,而不改变原始列表。
什么时候一个比另一个更受欢迎? 哪个更有效率?差多少? 执行list.sort()后,列表是否可以恢复到无序状态?
请使用为什么这些列表操作(方法)返回None,而不是结果列表?关闭OP无意中分配了.sort()结果的问题,而不是使用sorted或单独的语句。正确的调试将显示.sort()返回None,此时“为什么?”是剩下的问题。
当前回答
sorted(list)和list.sort()之间的区别是什么?
列表。sort就地改变列表并返回None Sorted接受任何可迭代对象,并返回一个已排序的新列表。
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
什么时候用哪个?
使用列表。当不希望保留原始排序顺序时进行排序 (因此,您将能够在内存中重用该列表) 您是列表的唯一所有者(如果该列表由其他代码共享) 如果你对它进行变异,你可能会在使用这个列表的地方引入bug。) 当您希望保留原始排序顺序或当您 希望创建一个只有本地代码拥有的新列表。
在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次提供相同的100,000长度的随机排序列表。
import timeit
setup = """
import random
random.seed(0)
lst = list(range(100000))
random.shuffle(lst)
"""
我认为这种更大的差异来自马丁提到的复制,但它并没有占主导地位在更古老更流行的答案中,这里时间的增加只有大约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,我就会用list。当我需要对列表进行排序时使用sort,并让它决定我的使用情况。
其他回答
sorted(list)和list.sort()之间的区别是什么?
列表。sort就地改变列表并返回None Sorted接受任何可迭代对象,并返回一个已排序的新列表。
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
什么时候用哪个?
使用列表。当不希望保留原始排序顺序时进行排序 (因此,您将能够在内存中重用该列表) 您是列表的唯一所有者(如果该列表由其他代码共享) 如果你对它进行变异,你可能会在使用这个列表的地方引入bug。) 当您希望保留原始排序顺序或当您 希望创建一个只有本地代码拥有的新列表。
在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次提供相同的100,000长度的随机排序列表。
import timeit
setup = """
import random
random.seed(0)
lst = list(range(100000))
random.shuffle(lst)
"""
我认为这种更大的差异来自马丁提到的复制,但它并没有占主导地位在更古老更流行的答案中,这里时间的增加只有大约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,我就会用list。当我需要对列表进行排序时使用sort,并让它决定我的使用情况。
Sorted()返回一个新的排序列表,不影响原始列表。list.sort()对列表进行就地排序,改变列表索引,并返回None(像所有就地操作一样)。
Sorted()适用于任何可迭代对象,而不仅仅是列表。字符串,元组,字典(你会得到键),生成器等,返回一个包含所有元素的列表,排序。
当你想要改变列表时使用list.sort(),当你想要返回一个新的排序对象时使用sorted()。当你想对可迭代对象(而不是列表)排序时,使用sorted()。 对于列表,list.sort()比sorted()更快,因为它不需要创建副本。对于任何其他可迭代对象,您没有选择。 不,您不能检索原始位置。一旦调用list.sort(),原来的顺序就消失了。
.sort()函数将new list的值直接存储在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
我们看到的是原始列表(未修改且未排序)。Sorted没有改变原始的列表
[1, 2, -3, 4, 8, 5, 7, 14]
取相同的nums列表并对其应用排序函数,将改变实际的列表。
让我们来看看。
从我们的nums列表开始,以确保内容仍然相同。
nums
[-3, 1, 4, 5, 7, 8, 9, 14]
nums.sort()
现在原始的nums列表改变了,看看nums,我们看到原始的列表改变了,现在排序了。
nums
[-3, 1, 2, 4, 5, 7, 8, 14]
注意:sort()和sorted()之间最简单的区别是: 不返回任何值,而sorted()返回一个可迭代列表。
Sort()不返回任何值。
sort()方法只是按特定顺序对给定列表中的元素进行排序——升序或降序,而不返回任何值。
sort()方法的语法是:
list.sort(key=..., reverse=...)
或者,也可以使用Python的内置函数sorted() 出于同样的目的。排序函数返回排序列表
list=sorted(list, key=..., reverse=...)