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

时间:2014-03-16 20:16:10

标签: python list sorting copy in-place

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

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

6 个答案:

答案 0 :(得分:239)

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

sorted()适用于任何可迭代的,而不仅仅是列表。字符串,元组,字典(你将获得密钥),生成器等,返回包含所有元素的列表,已排序。

  • 当您想要改变列表时,请使用list.sort()sorted()当您想要新的已排序对象时。如果要对可迭代的内容进行排序,请使用sorted(),而不是列表尚未

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

  • 不,您无法检索原始位置。拨打list.sort()后,原始订单就消失了。

答案 1 :(得分:31)

  

sorted(list)list.sort()之间的区别是什么?

  • list.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
  

何时使用哪个?

  • 如果您不想保留原始排序顺序,请使用list.sort (因此,您将能够在内存中就地重复使用列表。)以及何时 您是该列表的唯一所有者(如果该列表由其他代码共享 并且你改变它,你可以引入使用该列表的错误。)
  • 如果要保留原始排序顺序或使用时,请使用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个整数列表中的结果,正如我们在此处看到的那样,我们已经证明an older list creation expense myth

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)
"""

我从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]

我还在一个小得多的类别上运行了上述内容,并发现新的sorted副本版本在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,并确定我的用法。

答案 2 :(得分:9)

主要区别在于sorted(some_list)会返回list

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

some_list.sort()对列表进行排序

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

注意,由于a.sort()没有返回任何内容,print a.sort()将打印None


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

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

答案 3 :(得分:0)

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

您必须明确地将sorted(list)的值存储在变量中。

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

答案 4 :(得分:0)

下面是一些简单的示例,以了解操作上的区别:

在此处查看数字列表:

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

在此列表上调用sorted时,sorted将对该列表进行复制。 (意味着您的原始列表将保持不变。)

让我们看看。

sorted(nums)

返回

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

再次查看nums

nums

我们看到原始列表(未更改且未排序)。 sorted并未更改原始列表

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

采用相同的nums列表并在其上应用sort函数,将更改实际列表。

让我们看看。

从我们的nums列表开始,以确保内容仍然相同。

nums

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

nums.sort()

现在原始的nums列表已更改,查看nums,我们看到原始列表已更改并进行了排序。

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

答案 5 :(得分:0)

  

注意:sort()和sorted()之间最简单的区别是:sort()   不会返回任何值,sorted()返回一个可迭代的列表。

sort()不返回任何值。

sort()方法仅按给定列表的元素以特定顺序排序-升序或降序,而不返回任何值。

sort()方法的语法为:

list.sort(key=..., reverse=...)
  

或者,您也可以使用Python的内置函数sorted()   出于相同的目的。排序函数返回排序列表

 list=sorted(list, key=..., reverse=...)