sorted(list) 和 list.sort() 之间有什么区别?

2024-12-19 09:23:00
admin
原创
133
摘要:问题描述:list.sort()对列表进行排序并替换原始列表,而sorted(list)返回列表的排序副本,而不改变原始列表。何时其中一个比另一个更受青睐?哪一个更有效率?效率高多少?list.sort()执行完之后列表可以恢复到未排序状态吗?请使用为什么这些列表操作(方法)返回 None,而不是结果列表?来...

问题描述:

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

  • 何时其中一个比另一个更受青睐?

  • 哪一个更有效率?效率高多少?

  • list.sort()执行完之后列表可以恢复到未排序状态吗?


请使用为什么这些列表操作(方法)返回 None,而不是结果列表?来关闭 OP 无意中分配结果.sort()而不是使用sorted或单独语句的问题。正确的调试会发现.sort()已返回None,此时“为什么?”是剩下的问题。


解决方案 1:

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

sorted()适用于任何可迭代对象,而不仅仅是列表。字符串、元组、字典(您将获得键)、生成器等,返回包含所有元素的列表,并进行排序。

  • list.sort()当您想改变列表时使用,sorted()当您想返回一个新的排序对象时使用。sorted()当您想对可迭代对象(还不是列表)进行排序时使用

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

  • 不可以,您无法恢复原始仓位。一旦您下单,list.sort()原始订单就没了。

解决方案 2:

sorted(list)vs 和有什么不一样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 个整数列表的结果,我们可以看到,我们推翻了旧的列表创建费用神话:

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]

收到一些反馈后,我决定再进行一次具有不同特征的测试。这里我提供了相同的随机排序列表,长度为 100,000,每次迭代 1,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当我需要就地对列表进行排序时,我会使用它,并让其决定我的用法。

解决方案 3:

主要区别在于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() 之后可以检索列表原始位置吗?

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

解决方案 4:

以下举几个简单的例子来说明实际操作中的差异:

请参阅此处的数字列表:

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:

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

sort() 不返回任何值。

sort() 方法只是按照特定顺序(升序或降序)对给定列表的元素进行排序,而不返回任何值。

sort() 方法的语法是:

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

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

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

解决方案 6:

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

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

对于短数据处理,速度也不会有差别;但对于长列表;您应该直接使用 .sort() 方法来快速工作;但同样您将面临不可逆转的操作。

解决方案 7:

使用 list.sort() 您可以改变列表变量,但使用 sorted(list) 您不会改变变量。

使用排序:

list = [4, 5, 20, 1, 3, 2]
list.sort()
print(list)
print(type(list))
print(type(list.sort())

应该返回这个:

[1, 2, 3, 4, 5, 20]
<class 'NoneType'>

但是使用sorted():

list = [4, 5, 20, 1, 3, 2]
print(sorted(list))
print(list)
print(type(sorted(list)))

应该返回这个:

[1, 2, 3, 4, 5, 20]
[4, 5, 20, 1, 3, 2]
<class 'list'>
相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   1572  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1355  
  信创产品在政府采购中的占比分析随着信息技术的飞速发展以及国家对信息安全重视程度的不断提高,信创产业应运而生并迅速崛起。信创,即信息技术应用创新,旨在实现信息技术领域的自主可控,减少对国外技术的依赖,保障国家信息安全。政府采购作为推动信创产业发展的重要力量,其对信创产品的采购占比情况备受关注。这不仅关系到信创产业的发展前...
信创和国产化的区别   0  
  信创,即信息技术应用创新产业,旨在实现信息技术领域的自主可控,摆脱对国外技术的依赖。近年来,国货国用信创发展势头迅猛,在诸多领域取得了显著成果。这一发展趋势对科技创新产生了深远的推动作用,不仅提升了我国在信息技术领域的自主创新能力,还为经济社会的数字化转型提供了坚实支撑。信创推动核心技术突破信创产业的发展促使企业和科研...
信创工作   0  
  信创技术,即信息技术应用创新产业,旨在实现信息技术领域的自主可控与安全可靠。近年来,信创技术发展迅猛,对中小企业产生了深远的影响,带来了诸多不可忽视的价值。在数字化转型的浪潮中,中小企业面临着激烈的市场竞争和复杂多变的环境,信创技术的出现为它们提供了新的发展机遇和支撑。信创技术对中小企业的影响技术架构变革信创技术促使中...
信创国产化   0  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用