当前位置: 首页 > 科技观察

Python神器函数sorted():你不得不看的3个特性

时间:2023-03-14 11:55:51 科技观察

作为一种通用语言,Python逐渐流行于各个学术和工业领域,用于科学计算、工程、Web开发等诸多用途。Python的一个迷人特性是它非常灵活,可以对同一个函数有多个实现。让我们考虑以下简单示例。>>>#sortalistusingsort()>>>names0=['Danny','Johnny','Billy','Donny']>>>names0.sort()>>>names0['Billy','Danny','Donny','Johnny']>>>>>>#sortalistusingsorted()>>>names1=['Danny','Johnny','Billy','Donny']>>>sorted(names1)['Billy','Danny','Donny','Johnny']>>>["Billy","Danny","Donny","Johnny"]在上面的代码中,我们创建了两个列表:names0和names1,并使用sort()和sorted()函数分别对它们进行排序。显然,我们可以按相同的顺序进入列表。尽管sort()和sorted()函数之间有相似之处,但我想指出的是,几乎总是使用sorted()而不是sort()。这是三个原因。1.与任何迭代器的兼容性第一个原因是sorted()函数更灵活,因为它可以与任何可迭代对象一起使用。相反,sort()函数仅适用于列表。如果你不知道iterable是什么,你可以参考我之前的文章。简而言之,可迭代对象是可以在可迭代对象中迭代的Python对象,例如元组、列表、集合和字典。让我们根据兼容的数据类型比较sorted()和sort()。需要注意的一件事是,这两个函数的使用方式存在细微差别。sorted()函数将一个可迭代对象作为参数,sort()函数的调用者使用点表示法调用该函数。>>>#sortatuple>>>_=(3,5,4).sort()Traceback(mostrecentcallast):File"",line1,inAttributeError:'tuple'对象没有属性'sort'>>>_=sorted((3,5,4))>>>>>>#sortadictionary>>>_={2:'二',0:'零',1:'一'}.sort()Traceback(mostrecentcallast):File"",line1,inAttributeError:'dict'objecthasnoattribute'sort'>>>_=sorted({2:'two',0:'zero',1:'one'})>>>>>>#sortaset>>>_=set([2,3,4]).sort()Traceback(mostrecentcallast):File"",line1,inAttributeError:'set'objecthasnoattribute'sort'>>>_=sorted(set([2,3,4]))如上面代码所示,元组、字典和集合不能调用sort()函数。事实上,sort()函数是列表对象的实例方法,而不是其他集合对象的实例方法,也就是说这个函数只对列表对象有效。相比之下,元组、字典和集合都可以通过sorted()函数进行排序,因为所有这些数据类型都是可迭代的,因此适合与sorted()函数一起使用。2.创建列表方便的第二个原因是sorted()函数将可迭代对象按照想要的顺序排序后返回一个列表对象。所以这是构建新列表的便捷方法。但是,sort()函数会更改调用此方法的列表的顺序,我们将此顺序称为就地排序。此外,此函数隐式返回None(有时,当隐式返回值为None时,我们可以说它不返回任何内容)。让我们考虑以下假设示例。我们从一个名为sales_dict的字典开始,它保存了一整年的销售记录。我们想要创建一个按销售额降序排列的记录列表。>>>#recordsofsalesinadictionary>>>sales_dict={'Spring':1000,'Summer':950,'Fall':1030,'Winter':1200}>>>>>>#createalistobjectofsalesrecords>>>sales_list0=sorted(sales_dict.items(),key=lambdax:x[1],reverse=True)>>>sales_list0[('冬季',1200),('秋季',1030),('春季',1000),('夏季',950)]>>>>>>sales_list1=list(sales_dict.items())>>>sales_list1.sort(key=lambdax:x[1],reverse=True)>>>sales_list1[('冬季',1200),('Fall',1030),('Spring',1000),('Summer',950)]在上面的代码中,我们只需要写一行代码,使用sorted()函数即可得到所有想要的结果。但是,使用sort()函数,我们必须编写两行代码。值得注意的是,有人可能会误会,我们不能使用点符号将这两行组合起来以生成所需的列表对象。>>>#combinethtwolines>>>sales_list2=list(sales_dict.items()).sort(key=lambdax:x[1],reverse=True)>>>sales_list2>>>type(sales_list2)>>>print(sales_list2)None如上面的代码所示,通过组合这两行,我们得到了None值。这是因为sort()函数的返回值是None,而不是调用该函数的列表对象。3.与迭代集成既然sorted()函数返回一个列表,而sort()函数返回None,那么这种区别意味着什么?好吧,在很多情况下,我们期望可迭代对象,但没有NoneType对象。一种这样的场景是迭代,毕竟这是我们经常对列表对象执行的关键操作。考虑以下示例。我们有两本字典,分别保存第一学期和第二学期的成绩。目标是创建一个报告卡,总结每个学生的表现,按姓名排序。>>>#testresultsforthefirstsemester>>>results1={'John':95,'Danny':80,'Zack':98}>>>>>>#testresultsforthesecondsemester>>>results2={'Danny':84,'Zack':95,'John':88}>>>>>>#generatethereportcard>>>forname,scoreinserted(results2.items()):...print(f'{name}|Spring:{results1[name]}|Fall:{score}')...Danny|Spring:80|Fall:84John|Spring:95|Fall:88Zack|Spring:98|Fall:95在上面的代码中,我们注意到两个字典做没有所需的输出顺序,因此,我们将使用sorted()函数对字典进行排序。如您所见,我们可以将排序后的结果直接集成到for循环中,因为sorted()函数返回排序后的列表。您可能已经预料到如果我们在这种情况下尝试使用sort()函数会发生什么。请参阅下面的更多细节。>>>forname,scoreinlist(results2.items()).sort():...print(f'{name}|Spring:{results1[name]}|Fall:{score}')...Traceback(mostrecentcallast):File"",line1,inTypeError:'NoneType'objectisnotiterable摘要在本文中,我们讨论了几乎应该始终使用sorted()函数而不是sort()的三个原因功能。sorted()函数更灵活,因为它适用于任何可迭代对象,这与仅适用于列表的sort()函数不同。sorted()函数是创建排序列表的便捷方法。sorted()函数可以轻松地与迭代集成。结束思考最后但同样重要的是,您可能想知道什么时候应该考虑使用sort()函数。对于这个问题我没有确切的答案,但我能想到的一种情况是当我们只处理列表对象而不希望返回列表时。毕竟sorted()函数会生成一个新的列表,所以当列表特别大的时候,使用sorted()函数来创建一个新的列表内存效率不高。考虑这个简单的例子。我们需要对每个嵌套列表进行排序。在某些情况下,列表可能非常大。使用sort()函数只会对原始列表进行排序,从而避免不必要地创建新的列表对象。>>>#simplifiednestedlists;每个列表可以更大>>>group_scores=[[7,3,5],[3,2,8],[9,4,5]]>>>forscoresingroup_scores:...scores.sort()...>>>group_scores[[3,5,7],[2,3,8],[4,5,9]]译文:https://medium.com/swlh/3-reasons-why-你应该几乎总是使用sorted-in-python-9fe122e6ce71